在使用open()获得的流上使用io.BufferedReader?

时间:2012-04-17 21:11:58

标签: python io python-2.7 buffered

我想使用缓冲流,因为我想使用peek()方法向前看,但是使用我的流和另一个需要类文件对象的方法。 (我使用seek()但可能必须处理不支持随机访问的管道输入I / O.)

但是这个测试用例失败了:

AttributeError:'file'对象没有属性'_checkReadable'

import sys
import io

srcfile = sys.argv[1]
with open(srcfile, 'rb') as f:
    fbuf = io.BufferedReader(f)
    print fbuf.read(20)

发生了什么,我该如何解决?我以为BufferedReader旨在缓冲流。如果是这样,为什么open()函数不返回与它兼容的东西?

3 个答案:

答案 0 :(得分:18)

通过print语句的外观,您使用的是Python 2.在该版本中,file不是BufferedReader构造函数的有效参数:

  

在Python 2.x中,这被提议作为内置file对象的替代,但在Python 3.x中,它是访问文件和流的默认接口。 (1

您应该使用io.open代替:

>>> f = io.open(".bashrc", "rb")

如果你这样做,就没有必要在BufferedReader中明确地将它包装起来,因为这正是io.open默认返回的内容:

>>> type(f)
<type '_io.BufferedReader'>

有关详细信息,请参阅its docs;有一个buffering参数控制缓冲。

在Python 3中,open is io.open因此两个I / O库已合并为一个。似乎io被添加到Python 2.6中主要是为了向前兼容。

答案 1 :(得分:2)

您可以通过将buffering argument传递给open:

来设置缓冲量(以字节为单位)
import sys

srcfile = sys.argv[1]
with open(srcfile, 'rb', buffering=30) as f:
    print(f.peek(30))
    print(f.read(20))

这是BufferedReader

>>> with open("test.txt", 'rb', buffering=30) as f:
...     type(f)
<class '_io.BufferedReader'>

请注意,默认情况下,它被缓冲到1 - 行缓冲。

答案 2 :(得分:1)

在Python2中,如果必须使用file返回的open对象(或者由某些无法修改的模块例程提供),则可以使用{{1}获取的文件描述符} fileno()构造函数,然后将io.FileIO对象传递给io.FileIO构造函数。

因此,您可以按如下方式重写示例代码:

io.BufferedReader