Python文件.告诉给出错误的值位置

2024-09-27 21:28:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Python从现有文件中提取一些位置。这是我当前提取位置的代码:

    self.fh = open( fileName , "r+")
    p = re.compile('regGen regPorSnip begin')
    for line in self.fh :
        if ( p.search(line) ):
            self.porSnipStartFPtr = self.fh.tell()
            sys.stdout.write("found regPorSnip")

这个代码段用不同的搜索值重复了很多次(少了打开的文件),并且似乎有效:我得到了正确的消息,变量也有值。在

但是,使用下面的代码,第一个写入位置是错误的,而后续的写入位置是正确的:

^{pr2}$

我读过,由于Python倾向于“预读”,将某些read/readline选项传递给fh可能会导致错误的tell值。我看到的一个避免这种情况的建议是读取整个文件并重写它,这在我的应用程序中不是一个非常吸引人的解决方案。在

如果我将第一个代码段更改为:

  for line in self.fh.read() :
        if ( p.search(line) ):
            self.porSnipStartFPtr = self.fh.tell()
            sys.stdout.write("found regPorSnip")

那么self.fh.read()只返回字符而不是整行。搜索不匹配。对于self.fh.readline(),情况似乎也是如此。在

我的结论是,fh.tell只在写入操作后查询时返回有效的文件位置。在

有没有办法在读取/搜索时提取准确的文件位置?在

谢谢。在


Tags: 文件代码inselfforreadsearchif
2条回答

原因在文件对象的next()方法的文档中有解释(相当模糊):

When a file is used as an iterator, typically in a for loop (for example, for line in f: print line), the next() method is called repeatedly. This method returns the next input line, or raises StopIteration when EOF is hit. In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation), the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.

tell()返回的值反映了这个隐藏的预读缓冲区已达到的程度,通常比程序实际检索到的字符多几千字节。在

没有便携的方法来解决这个问题。如果需要将tell()与读取行混合使用,则使用文件的readline()方法。折衷是,作为获得可用的tell()结果的回报,使用readline()遍历一个大文件通常比使用for line in file_object:慢得多。在

代码

具体地说,将循环改为:

line = self.fh.readline()
while line:
    if p.search(line):
        self.porSnipStartFPtr = self.fh.tell()
        sys.stdout.write("found regPorSnip")
    line = fh.readline()

我不确定这是否是您真正想要的:tell()正在捕获下一行的开始位置。如果需要线路的开始的位置,则需要更改逻辑,如下所示:

^{pr2}$

或者用“半圈”来做:

while True:
    pos = self.fh.tell()
    line = self.fh.readline()
    if not line:
        break
    if p.search(line):
        self.porSnipStartFPtr = pos
        sys.stdout.write("found regPorSnip")

我想我不明白这个问题

>>> fh = open('test.txt')
>>> fh.tell()
0L
>>> fh.read(1)
'"'
>>> fh.tell()
1L
>>> fh.read(5)
'a" \n"'
>>> fh.tell()
7L

相关问题 更多 >

    热门问题