实现类似tail -f file功能

python版本py3

tail -f file是打印最后10行,然后跟踪文件追加的内容打印出来。

python3 以为本方式打开的话,不能回退(f.seek(-1,1)),所有以‘rb‘方式打开文件。

思路是f.seek(-n,2)从文件末尾回退n字节,然后f.readlines()读取文件,如果读到的少于10行,则再往前移动n字节,直到读到11行,然后打印出来,再跟踪打印文件追加的内容,并打印。

知识点:

f.tell()返回当前的文件位置

f.seek(n,m),m=0从文件开头往前或往后移到n字节,负数表示像文件头方向移动,正数表示向文件尾移动,m=1表示从文件指针当前位置移动,m=2表示从文件末尾开始移动,指针超出边界会报错。

f.seek(0,2)移到文件末尾

open(file,‘r‘)以文本方式打开,open(file,‘rb‘)以二进制方式打开。

由于文档是utf8或gbk编码保存的文件,以二进制方式打开文件读取到的是uft8或gbk编码(字节),所有打印是需要解码。

个人觉得在py2中,

"我”是str类型,utf8或gbk编码保存在内存中,只能进行解码成unicode操作:

py3中

‘我’是str类型,以unicode编码放在内存中,只能解码成bytes操作:

具体代码实现:

 1 #! -*- coding:utf-8 -*-
 2 # runing on python3
 3 import os,sys
 4 from time import sleep
 5 COUDING=sys.getfilesystemencoding()
 6
 7 class tail(object):
 8
 9     def __init__(self,n,filename,callback):
10         self._n = n
11         self.filename= filename
12         self.callback = callback
13         self.track()
14
15     def track(self):
16         if os.path.exists(self.filename):
17             if os.path.isfile(self.filename):
18                 try:
19                     with open(self.filename,‘rb‘) as f:
20                         self._file = f
21                         # 文件内部指针移到末尾
22                         f.seek(0, os.SEEK_END)
23                         self._len = f.tell()
24                         self.showline()
25                         while True:
26                             line = f.readline()
27                             self.callback(line)
28                             sleep(0.5)
29                 except Exception as e:
30                     print(e)
31             else:
32                 sys.stdout.write("tail: %s: cannot follow end of this type of file; giving up on this name"%self.filename)
33         else:
34             sys.stdout.write("tail: cannot open `%s‘ for reading: No such file or directory"%self.filename)
35
36     def showline(self):
37         # 假设每行100个字节
38         line_len = 100
39         n = self._n
40         # 文件字节数小于500,直接从头读文件,然后取后5行
41         if self._len < n * line_len:
42             self._file.seek(0)
43             lines = self._file.readlines()[-self._n:]
44             self.callback(lines)
45         else:
46             # 指针总文件末尾往文件头移动n * line-len个字节
47             while True:
48                 self._file.seek(-n*line_len,os.SEEK_END)
49                 lines = self._file.readlines()
50                 # 读n+1行,因为seek是以字节为单位移到的,如果移到一个中文字符的编码的中间,会出现UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0x80 in position 0: invalid start byte
51                 if len(lines) > self._n:
52                     self.callback(lines[-self._n:])
53                     return
54                 else:
55                     n += 1
56
57 def printline(lines):
58     if isinstance(lines,list):
59         for line in lines:
60             sys.stdout.write(line.decode(COUDING))
61     elif isinstance(lines,bytes):
62         sys.stdout.write(lines.decode(COUDING))
63
64 if __name__ == "__main__":
65     if len(sys.argv) < 2:
66         print("xxx")
67     else:
68         # 可加参数解析模块来获取文件名和显示最后多少行
69         tail(10,sys.argv[1],printline)
时间: 2024-10-29 19:12:27

实现类似tail -f file功能的相关文章

seek实现linux的tail -f 监视功能

1 # 监视filename文件的尾部内容(默认10行,相当于增加参数 -n 10),刷新显示在屏幕上.退出,按下CTRL+C. 2 ''' 3 相当于一个死循环 4 ''' 5 import time 6 with open('test.txt','rb') as f: 7 f.seek(0,2)#光标移到文件最后 8 while True: 9 line=f.readline() # 每次读一行光标移到最后 10 if line: 11 print(line.decode('utf-8'),

Notepad++ 中使用tail -f功能

想要notepad++中有tail -f的功能吗? 可以如下配置 Settings > Preferences > MISC 在 File Status Auto-Detection下 “Update Silently” 和 “Scroll to last line after update” 两个选项打上勾. 需要版本是Notepad++ 6.9.2 及其以上. --------------------- 原文地址:https://www.cnblogs.com/lidabo/p/98823

10min手写(五):面试题解析丨Python实现tail -f功能

作者:蜗牛 shengxinjing (woniuppp) · GitHub 写这篇文章的初衷是有人去面试遇到了这个笔试题,不知道怎么做,没有什么思路,就发到了Reboot 的交流群里,让大家一起讨论讨论. 关于这道题,简单说一下我的想法吧.当然,也有很好用的 pyinotify 模块专门监听文件变化,不过我更想介绍的,是解决的思路.毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不在于监控文件增量,而在于怎么打印最后面10行. 希望大家在读这篇文章前,对 Python 基础

python实现tail -f 功能

这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的pyinotify模块专门监听文件变化,不过我更想介绍的,是解决的思路,毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不在于监控文件增量,而在于怎么打印最后面10行 希望大家读这篇文章前,对python基础.处理文件和常用模块有一个简单的了解,知道下面几个名词是啥 open('a.txt') file.seek fi

tail -f 报错 file truncated

操作: 循环覆盖向tmp 文件写入坐标 tmp: -45.6976089525,-26.1528715421,-0.0188627654187 报错如下: -15.2517398838,-5.1216965666,1.62749776805tail: /opt/xxx/tmp: file truncated 解决: tail -f -n 1 /opt/xxx/tmp 原文地址:https://www.cnblogs.com/sea-stream/p/10773624.html

Hadoop-2.6.0上调用C的API实现类似云盘的功能

Hadoop-2.6.0上调用C的API实现类似云盘的功能(上传,下载,删除,重命名) 测试系统:CentOS6.6, hadoop-2.6.0 本次测试是调用hadoop下的C的API来访问HDFS实现类似云盘的上传,下载,删除,重命名的功能,其它功能还请有意者自行添加,废话少说,开始进入正题. 首先我们要能在hadoop-2.6.0上的C的API访问HDFS 详情可以访问:http://blog.csdn.net/u013930856/article/details/47660937 下面开

Linux命令 tail 加过滤功能

tail -n  行数 -f  文件夹路径以及 名字,用于查看log   后面可以追加  | grep   +名字  用于过滤 ps  aux|grep  文件  查看执行情况 例如: tail -n 40 -f /export/logs/main/monitor_ D.log | grep SendThread Linux命令 tail 加过滤功能

tali -f 和 tail -F 之间的区别

tail -f      等同于--follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止 tail -F     等同于--follow=name  --retry,根据文件名进行追踪,并保持重试,即该文件被删除或改名后,如果再次创建相同的文件名,会继续追踪 tail -F 相当于 tail --follow=name --retry man 手册: -f, --follow[={name|descriptor}] output appended data a

tail -f -n 0 /var/log/messages

<pre><font color="#CC0000"><b>[email protected]</b></font>:<font color="#3465A4"><b>~</b></font># tail -f -n 0 /var/log/messagesAug 18 22:19:42 kali kernel: [24663.263601] IPv6: ADD