Python csv读取器无法定位到行

0 投票
1 回答
2925 浏览
提问于 2025-04-18 10:09

我有一个简单的测试CSV文件:

1,2,3
4,5,6
7,8,9
10,11,12

我想读取前两行,然后回退一行,再读取下一行:

import csv
with open('test.csv', 'r') as f:
    reader = csv.reader(f)
    pos = f.tell()
    print 'pos: {0}'.format(pos)
    print reader.next()

    pos = f.tell()
    print 'pos: {0}'.format(pos)
    print reader.next()

    f.seek(pos)
    pos = f.tell()
    print 'pos: {0}'.format(pos)

    print reader.next()
    pos = f.tell()
    print 'pos: {0}'.format(pos)

但是,在第一次调用next()的时候,整个文件都被读取了:

pos: 0
['1', '2', '3']
pos: 27
['4', '5', '6']
pos: 27
Traceback (most recent call last):
  File "<stdin>", line 15, in <module>
StopIteration

我尝试设置buffering=0,但问题依然存在。如果我直接使用文件对象来调用readline(),一切都正常。有没有什么办法可以防止CSV读取器在第一次调用next()时读取多行?

1 个回答

4

我觉得这可能不行。关于 file.next 的文档解释了原因:

为了让使用 for 循环遍历文件的每一行变得更高效(这是一种非常常见的操作),next() 方法使用了一个隐藏的预读缓冲区。由于使用了这个预读缓冲区,next() 和其他文件方法(比如 readline())结合使用时就会出现问题。 不过,如果你使用 seek() 方法将文件移动到一个绝对位置,就会清空这个预读缓冲区。

实际上,如果你使用 io 模块来打开文件(在 Python 3.x 中这是默认的做法),会抛出一个特定的 IOError 错误,告诉你这样做是不被允许的:

  File "./c.py", line 12, in <module>
    pos = f.tell()
IOError: telling position disabled by next() call

撰写回答