撤销文件readline()操作使文件指针恢复原始状态

46 投票
5 回答
58923 浏览
提问于 2025-04-16 02:55

我正在用只读模式浏览一个文本文件的指针,使用file.readline()来查找一行特定的内容。一旦找到那一行,我想把文件指针传递给一个方法,而这个方法希望文件指针正好在那一行的开始位置(而不是在那一行之后)。

我该怎么做才能让文件指针“撤销”一次file.readline()操作呢?

5 个回答

6

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

import itertools

# do something to the marker line and everything after
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
15

在你调用 readline 之前,可以用 thefile.tell() 来记录当前文件指针的位置。如果需要的话,可以用 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'
>>> 

正如你所看到的,seektell 这对组合就像是在“撤销” readline 移动文件指针的操作。当然,这个方法只能在真正可以移动指针的文件上使用,比如磁盘文件,而不能在一些像是用套接字的 makefile 方法创建的类文件对象上使用。

66

你需要在读取一行之前,先用 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()

我不太记得在 for line in file 循环里面调用 file.seek() 是否安全,所以我通常会直接写成 while 循环。其实可能还有更符合 Python 风格的方法来实现这个。

撰写回答