实现类似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操作:

具体代码实现:
#! -*- coding:utf-8 -*-
# runing on python3
import os,sys
from time import sleep
COUDING=sys.getfilesystemencoding() class tail(object): def __init__(self,n,filename,callback):
self._n = n
self.filename= filename
self.callback = callback
self.track() def track(self):
if os.path.exists(self.filename):
if os.path.isfile(self.filename):
try:
with open(self.filename,'rb') as f:
self._file = f
# 文件内部指针移到末尾
f.seek(0, os.SEEK_END)
self._len = f.tell()
self.showline()
while True:
line = f.readline()
self.callback(line)
sleep(0.5)
except Exception as e:
print(e)
else:
sys.stdout.write("tail: %s: cannot follow end of this type of file; giving up on this name"%self.filename)
else:
sys.stdout.write("tail: cannot open `%s' for reading: No such file or directory"%self.filename) def showline(self):
# 假设每行100个字节
line_len = 100
n = self._n
# 文件字节数小于500,直接从头读文件,然后取后5行
if self._len < n * line_len:
self._file.seek(0)
lines = self._file.readlines()[-self._n:]
self.callback(lines)
else:
# 指针总文件末尾往文件头移动n * line-len个字节
while True:
self._file.seek(-n*line_len,os.SEEK_END)
lines = self._file.readlines()
# 读n+1行,因为seek是以字节为单位移到的,如果移到一个中文字符的编码的中间,会出现UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
if len(lines) > self._n:
self.callback(lines[-self._n:])
return
else:
n += 1 def printline(lines):
if isinstance(lines,list):
for line in lines:
sys.stdout.write(line.decode(COUDING))
elif isinstance(lines,bytes):
sys.stdout.write(lines.decode(COUDING)) if __name__ == "__main__":
if len(sys.argv) < 2:
print("xxx")
else:
# 可加参数解析模块来获取文件名和显示最后多少行
tail(10,sys.argv[1],printline)
实现类似tail -f file功能的更多相关文章
- Notepad++ 中使用tail -f功能
想要notepad++中有tail -f的功能吗? 可以如下配置 Settings > Preferences > MISC 在 File Status Auto-Detection下 “ ...
- Pytho实现tail -f
实现Python版的tail -f功能 tail -f 的功能非常好用.我们用Python也可以实现这样的功能.实现的原理是通过Python版本的inotify获得文件的更新消息,从而读取更新的行.p ...
- tail -f 在对文件进行动态追踪时失效的问题
在我是用 tail -f file.txt 对这个文件进行动态追踪时: 我重新打开一个新的终端进行vim编辑这个文件并且保存 这是我们发现,tail -f file.txt'动态追踪的这个文件没有任何 ...
- python10min系列之面试题解析:python实现tail -f功能
同步发布在github上,跪求star 这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的 ...
- python实现tail -f 功能
这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的pyinotify模块专门监听文件变化, ...
- python实现tail -f功能
这篇文章最初是因为reboot的群里,有人去面试,笔试题有这个题,不知道怎么做,什么思路,就发群里大家讨论 我想了一下,简单说一下我的想法吧,当然,也有很好用的pyinotify模块专门监听文件变化, ...
- awk -f program.file 功能使用
一.awk -f program.file 功能使用 一直没有使用过awk的-f功能,感觉鸡肋,不是很实用,更多的是因为没有需求的原因 下面介绍下awk -f的使用方法 awk可以指定默认的文件路径, ...
- Python 10min系列之面试题解析丨Python实现tail -f功能
关于这道题,简单说一下我的想法吧.当然,也有很好用的 pyinotify 模块专门监听文件变化,不过我更想介绍的,是解决的思路. 毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不 ...
- 如何用GO实现一个tail -f功能以及相应的思维发散
此文已由作者杨望暑授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 背景 在服务端查看log会经常使用到tail -f命令实时跟踪文件变化. 那么问题来了, 如果自己写一个同样 ...
随机推荐
- java中为什么要使用代理
引入代理: 我们为什么要引入java的代理,除了当前类能够提供的功能外,我们还需要补充一些其他功能. 最容易想到的情况就是权限过滤,我有一个类做某项业务,但是由于安全原因只有某些用户才可以调用这个类, ...
- div高度自适应窗口高度布局
给body和html都设置height:100%:然后子元素用百分比设置高度
- C# DataGridView控件动态添加新行
C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...
- 平台播放声音(ext.js)
首先把需要的两个js文件放在public/core路径下 (文件已经上传到博客了) 音频文件放在文件一级目录 代码:JxCustom.loadAudio("wav/NG.wav") ...
- 阿里 RPC 框架 DUBBO 初体验
最近研究了一下阿里开源的分布式RPC框架dubbo,楼主写了一个 demo,体验了一下dubbo的功能. 快速开始 实际上,dubbo的官方文档已经提供了如何使用这个RPC框架example代码,基于 ...
- python 中如何判断list中是否包含某个元素
在python中可以通过in和not in关键字来判读一个list中是否包含一个元素 theList = ['a','b','c'] if 'a' in theList: print 'a in th ...
- 51 nod 1350 斐波那契表示
每一个正整数都可以表示为若干个斐波那契数的和,一个整数可能存在多种不同的表示方法,例如:14 = 13 + 1 = 8 + 5 + 1,其中13 + 1是最短的表示(只用了2个斐波那契数).定义F(n ...
- Swoole http server + yaf, swoole socket server + protobuf 等小结
拥抱swoole, 拥抱更好的php Swoole 是什么? Yaf 是什么? 接触swoole已经4年多了,一直没有好好静下心来学习.一直在做web端的应用,对网络协议和常驻内存型服务器一窍不通.一 ...
- weblogic启动一闪而过
点击startWebLogic.cmd的时候,一闪而过 我的原因:JAVA_HOME中的路径是不能带有空格:我的电脑是64位的,jdk(32位)安装路径默认带有空格还有括号,所以重新装jdk,装在没有 ...
- 【bzoj4709】[Jsoi2011]柠檬 决策单调性+dp
Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...