Python: Undo a file readline() operation so file-pointer is back in original state

流过昼夜 提交于 2019-11-26 15:45:48

问题


I'm browsing through a Python file pointer of a text file in read-only mode using file.readline() looking for a special line. Once I find that line I want to pass the file pointer to a method that is expecting the file pointer to be at the START of that readline (not right after it.)

How do I essentially undo one file.readline() operation on a file pointer?


回答1:


You have to remember the position by calling file.tell() before the readline and then calling file.seek() to rewind. Something like:

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()

I can't recall if it is safe to call file.seek() inside of a for line in file loop so I usually just write out the while loop. There is probably a much more pythonic way of doing this.




回答2:


You record the starting point of the line with thefile.tell() before you call readline, and get back to that point, if you need to, with 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'
>>> 

as you see, the seek/tell "pair" is "undoing", so to speak, the file pointer movement performed by readline. Of course, this can only work on an actual seekable (i.e., disk) file, not (e.g.) on file-like objects built w/the makefile method of sockets, etc etc.




回答3:


If your method simply wants to iterate through the file, then you could use itertools.chain to make an appropriate iterator:

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



回答4:


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



回答5:


If you don't know the last line because you didn't visit it you can read backwards until you see a newline character:

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


来源:https://stackoverflow.com/questions/3505479/python-undo-a-file-readline-operation-so-file-pointer-is-back-in-original-sta

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!