file.tell()不一致 [英] file.tell() inconsistency

查看:65
本文介绍了file.tell()不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人碰巧知道为什么当您以这种方式遍历文件时:

Does anybody happen to know why when you iterate over a file this way:

f = open('test.txt', 'r')
for line in f:
    print "f.tell(): ",f.tell()

输出:

f.tell(): 8192
f.tell(): 8192
f.tell(): 8192
f.tell(): 8192

我始终从tell()获取错误的文件索引,但是,如果我使用readline,则会为tell()获得适当的索引:

I consistently get the wrong file index from tell(), however, if I use readline I get the appropriate index for tell():

f = open('test.txt', 'r')
while True:
    line = f.readline()
    if (line == ''):
        break
    print "f.tell(): ",f.tell()

输出:

f.tell(): 103
f.tell(): 107
f.tell(): 115
f.tell(): 124

我正在运行python 2.7.1 BTW.

I'm running python 2.7.1 BTW.

推荐答案

使用打开的文件作为迭代器会使用预读缓冲区来提高效率.结果,当您遍历行时,文件指针将在文件中大步前进.

Using open files as an iterator uses a read-ahead buffer to increase efficiency. As a result, the file pointer advances in large steps across the file as you loop over the lines.

文件对象文档中:

为了使for循环成为遍历文件行的最有效方法(一种非常常见的操作),next()方法使用了隐藏的预读缓冲区.使用预读缓冲区的结果是,将next()与其他文件方法(例如readline())结合使用是不正确的.但是,使用seek()将文件重新定位到绝对位置将刷新预读缓冲区.

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(),请勿将文件对象用作迭代器.您可以将.readline()变成迭代器(以性能损失为代价):

If you need to rely on .tell(), don't use the file object as an iterator. You can turn .readline() into an iterator instead (at the price of some performance loss):

for line in iter(f.readline, ''):
    print f.tell()

这使用 iter()函数 sentinel参数将任何可调用对象转换为迭代器.

This uses the iter() function sentinel argument to turn any callable into an iterator.

这篇关于file.tell()不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆