最近有一个项目需要去读取日志文件的后面几行 ,但不想去直接调用linux系统自带的tail。这样太没有挑战性了。
于是自己动手写了一个。
参考了 //www.greatytc.com/p/d5c7f16687bd。这篇文章中的实现。但该实现在文件行较长,行数较多的情况下会有非常严重的性能问题。所以我动手改进了代码。
代码判断行数是用的找已读取的字符串中的“\n”的数目。
这个实现的好处之一是不需要重复读文件。当然,行较长较多时也会消耗比较大的内存。
这个实现是肯定比不上系统自己的。但它毕竟是我自己写的。
# coding:utf-8
# coding:utf-8
import argparse
__author__ = 'bary'
"""
2018年12月14日 19时00分
"""
PAGE = 4096
parser = argparse.ArgumentParser(description="")
parser.add_argument("-n", "--number", default=5, help="", type=int)
parser.add_argument("-f", "--file", default="/var/log/jiankong.log", help="")
def tail(line, src):
"""性能较好,虽然还是比linux自带的tail慢很多 囧 """
buf = []
with open(src, "rb") as f:
f.seek(0, 2)
f_len = f.tell()
now = f_len
a_num_n = 0
while 1:
if now - PAGE >= 0:
n_read = PAGE
else:
n_read = now
seek_n = (f_len - now) + n_read
f.seek(-seek_n, 2)
temp = f.read(n_read)
buf.append(temp)
a_num_n += temp.count("\n")
if a_num_n - 1 >= line or now <= PAGE:
buf.reverse()
return ''.join(buf).splitlines()[-line:]
else:
now -= PAGE
f.seek(-seek_n, 2)
if __name__ == "__main__":
args = parser.parse_args()
for i in tail(args.number, args.file):
print i
本文作者: 王炎杰
本文链接://www.greatytc.com/p/fb632c63e444
版权声明: 转载请注明出处!