撤消文件 readline() 操作,使文件指针回到原始状态

发布于 2024-09-14 22:04:16 字数 156 浏览 6 评论 0原文

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

我如何基本上撤消一个 file.readline() 操作文件指针?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟织青萝梦 2024-09-21 22:04:16

您必须通过在读取行之前调用 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 循环。可能有一种更Pythonic 的方法可以做到这一点。

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.

奶茶白久 2024-09-21 22:04:16

在调用 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'
>>> 

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

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.

三生路 2024-09-21 22:04:16

如果您的方法只是想迭代文件,那么您可以使用 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

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

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
一场信仰旅途 2024-09-21 22:04:16
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
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
伤感在游骋 2024-09-21 22:04:16

如果您不知道最后一行,因为您没有访问过它,您可以向后阅读,直到看到换行符:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文