python file seek tell
Python面试题解析丨Python实现tail -f功能
文件指针定位之 seek 方法
seek(offset, from)
offset :文件指针偏移量(很多博客在这里将offset定义为指针偏移量,但是目前我的看法是这里定义为指针的相对位置)
from : 0-文件开头 1-当前位置 2-文件末尾(这里的0,1,2只是代表了文件位置
代码示例
file_name = "new2.txt"
fp = open(file_name, "r",encoding='utf8')
print("当前文件指针位置 : ", fp.tell())
str = fp.read(18)
print("fp.read(18)读取到的数据 : ", str)
print("当前文件位置 : ", fp.tell())
fp.seek(9,0) # 见说明3
print("fp.seek(9,0),当前文件指针位置 : ", fp.tell())
str=fp.readline()
print("fp.readline()读取到的数据 : ", str)
print("当前文件指针位置 : ", fp.tell())
实战例子通过python实现Linux tail 功能
with open('test.txt') as f:
f.seek(0,2)
while True:
last_pos = f.tell()
line = f.readline()
if line:
print line
优化版1
# coding=utf-8
import sys
import time
def readCase(filePath):
file = open(filePath, 'r', encoding='UTF-8')
content = file.readlines()
# print(content)
file.close()
return content
def readCase2(filePath):
with open(filePath, 'r', encoding='UTF-8') as file:
content = file.readlines()
return content
class Tail():
def __init__(self,file_name,callback=sys.stdout.write):
self.file_name = file_name
self.callback = callback
def follow(self):
try:
with open(self.file_name, 'r', encoding='UTF-8') as f:
f.seek(0,2)
while True:
line = f.readline()
if line:
self.callback(line)
time.sleep(1)
except :
print('打开文件失败,囧,看看文件是不是不存在,或者权限有问题')
#
#
# 使用默认的sys.stdout.write打印到屏幕
py_tail = Tail('new2.txt')
py_tail.follow()
# ans = readCase2('new2.txt')
# print(ans)
# # 自己定义处理函数
# def test_tail(line):
# print( 'xx'+line+'xx')
#
# py_tail1 = Tail('new2.txt', test_tail)
# py_tail1.follow()
优化版2 输出末尾10行
import sys
import time
class Tail():
def __init__(self,file_name,callback=sys.stdout.write):
self.file_name = file_name
self.callback = callback
def follow(self,n=10):
try:
with open(self.file_name, 'r', encoding='UTF-8') as f:
self.showLastLine(f,n)
f.seek(0,2)
while True:
line = f.readline()
if line:
self.callback(line)
except:
print('打开文件失败,囧,看看文件是不是不存在,或者权限有问题')
def showLastLine(self,f, n):
# print(f.readlines())
last_lines = f.readlines()[-n:]
for line in last_lines:
self.callback(line)
# 使用默认的sys.stdout.write打印到屏幕
py_tail = Tail('new2.txt')
py_tail.follow()
优化3
# coding=utf-8
import sys
import time
class Tail():
def __init__(self,file_name,callback=sys.stdout.write):
self.file_name = file_name
self.callback = callback
def follow(self,n=10):
try:
# 打开文件
with open(self.file_name) as f:
self._file = f
self._file.seek(0,2)
# 存储文件的字符长度
self.file_length = self._file.tell()
# 打印最后10行
self.showLastLine(n)
# 持续读文件 打印增量
while True:
line = self._file.readline()
if line:
self.callback(line)
time.sleep(1)
except:
print('打开文件失败,囧,看看文件是不是不存在,或者权限有问题')
def showLastLine(self, n):
# 一行大概100个吧 这个数改成1或者1000都行
len_line = 100
# n默认是10,也可以follow的参数传进来
read_len = len_line*n
# 用last_lines存储最后要处理的内容
while True:
# 如果要读取的1000个字符,大于之前存储的文件长度
# 读完文件,直接break
if read_len>self.file_length:
self._file.seek(0)
last_lines = self._file.read().split('\n')[-n:]
break
# 先读1000个 然后判断1000个字符里换行符的数量
self._file.seek(-read_len, 2)
last_words = self._file.read(read_len)
# count是换行符的数量
count = last_words.count('\n')
if count>=n:
# 换行符数量大于10 很好处理,直接读取
last_lines = last_words.split('\n')[-n:]
break
# 换行符不够10个
else:
# break
#不够十行
# 如果一个换行符也没有,那么我们就认为一行大概是100个
if count==0:
len_perline = read_len
# 如果有4个换行符,我们认为每行大概有250个字符
else:
len_perline = read_len/count
# 要读取的长度变为2500,继续重新判断
read_len = len_perline * n
for line in last_lines:
self.callback(line+'\n')
if __name__ == '__main__':
py_tail = Tail('test.txt')
py_tail.follow(20)