查看 file.tell(),我希望它能给我一个可以用于 file.seek()的职位。但我不确定如何在实践中这样做,因为tell()似乎从一开始就指向文件的末尾。
这里有一些测试数据:
i am line 1
i am line 2
i am line 3
程序:
with open("./test_tell.txt") as fi:
for line in fi:
seekto = fi.tell()
print "position:%d" % fi.tell()
print(line)
#we're at the end
fi.seek(seekto)
print("seekto:%s" % fi.read())
fi.seek(seekto-5)
print("seekto-5:%s" % fi.read())
输出:
position:35
i am line 1
position:35
i am line 2
position:35
i am line 3
seekto:
seekto-5:ine 3
请注意我从一开始就到达35,文件结尾?我怎样才能使迭代器只在前进到每一行的末尾,这样tell
实际上对知道我在文件中的位置很有用?我感觉整个文件被读作优化,这就是为什么告诉我最后的权利。
我关心的原因是我正在研究一个基于状态机的程序,该程序运行在一个大文件中。出于调试目的,我想提供一个 n行返回窗口,当前行和前面的n行。希望寻求使用tell位置来提前读取同一文件的不同文件。因为告诉我总是指出结束。
Python 2.7,以防文件语义发生变化。
答案 0 :(得分:2)
您的示例不会在Python 2中触发错误,但是因为性能原因,因为使用迭代器读取缓冲会失败。
大多数情况下,当您逐行阅读时,您并不关心文件位置(更一般地说:您不关心文本文件中的文件位置)
因此在1次操作中读取文件,留下文件的结束偏移量。
请注意,Python 3更严格:在迭代后使用tell
获得异常。
OSError: telling position disabled by next() call
一种方法是
我的代码:适用于python 2& python 3(需要解码才能摆脱字节表示以更好地完成):
with open("./text.txt","rb") as fi:
current_offset = 0
line_pos=[]
for line in fi:
line_pos.append(current_offset)
current_offset += len(line)
print(line)
fi.seek(line_pos[1])
print("seekto:%s" % next(fi))
结果:
b'i am line 1\r\n'
b'i am line 2\r\n'
b'i am line 3\r\n'
seekto:b'i am line 2\r\n'
请注意,我在第二行的开头成功搜索,因此next(fi)
读取了第二行。
当然,它仍然可以将行存储在list
中,除非它太大,在这种情况下这种方法有一些兴趣(即:如果文件是没有被其他进程写回,否则线路偏移信息需要更新)