Python:撤消文件readline()操作,使文件指针恢复原始状态

时间:2010-08-17 18:02:32

标签: python file-io readline readlines

我正在使用file.readline()查找特殊行,以只读模式浏览文本文件的Python文件指针。一旦找到该行,我想将文件指针传递给一个方法,该方法期望文件指针位于该readline的START位置(不在它之后)。

如何在文件指针上实质上撤消一个file.readline()操作?

5 个答案:

答案 0 :(得分:43)

您必须通过在读取行之前调用file.tell()然后调用file.seek()来回放来记住该位置。类似的东西:

fp = open('myfile')
last_pos = fp.tell()
line = fp.readline()
while line != '':
  if line == 'SPECIAL':
    fp.seek(last_pos)
    other_function(fp)
    break
  last_pos = fp.tell()
  line = fp.readline()

我不记得在file.seek()循环中调用for line in file是否安全,所以我通常只写出while循环。这可能有更多的pythonic方式。

答案 1 :(得分:11)

在致电thefile.tell()之前,您会使用readline记录该行的起点,如果需要,请使用thefile.seek返回该点。

>>> with open('bah.txt', 'w') as f:
...   f.writelines('Hello %s\n' % i for i in range(5))
... 
>>> with open('bah.txt') as f:
...   f.readline()
...   x = f.tell()
...   f.readline()
...   f.seek(x)
...   f.readline()
... 
'Hello 0\n'
'Hello 1\n'
'Hello 1\n'
>>> 

如你所见,seek / tell“对”是“撤消”,可以说是readline执行的文件指针移动。当然,这只能用于实际可搜索(即磁盘)文件,而不是(例如)在使用套接字的makefile方法等构建的类文件对象上。

答案 2 :(得分:4)

如果您的方法只想迭代文件,那么您可以使用itertools.chain来创建一个合适的迭代器:

import itertools

def process(it):
    for line in it:
        print line,

with open(filename,'r') as f:
    for line in f:
        if 'marker' in line:
            it=itertools.chain((line,),f)
            process(it)
            break

答案 3 :(得分:1)

fin = open('myfile')
for l in fin:
    if l == 'myspecialline':
        # Move the pointer back to the beginning of this line
        fin.seek(fin.tell() - len(l))
        break
# now fin points to the start of your special line

答案 4 :(得分:0)

如果由于未访问而不知道最后一行,则可以向后阅读,直到看到换行符为止:

with open(logfile, 'r') as f:
    # go to EOF
    f.seek(0, os.SEEK_END)
    nlines = f.tell()
    i=0
    while True:
        f.seek(nlines-i)
        char = f.read(1)
        if char=='\n':
            break
        i+=1