peek()
メソッドを使用して先読みするため、バッファリングされたストリームを使用したいが、ファイルのようなオブジェクトを期待する別のメソッドでストリームを使用したい。 (seek()
を使用しますが、ランダムアクセスをサポートしていないパイプインI/Oを処理する必要がある場合があります。)
しかし、このテストケースは失敗します。
AttributeError: 'file' object has no attribute '_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()
関数はそれと互換性のあるものを返さないのですか?
print
ステートメントの外観から、Python 2.を使用しています。そのバージョンでは、file
はBufferedReader
コンストラクタ:
Python 2.xでは、これは組み込みの
file
オブジェクトの代替として提案されていますが、Python 3.xではファイルとストリームにアクセスするためのデフォルトのインターフェースです( 1 )
代わりにio.open
を使用してください:
>>> f = io.open(".bashrc", "rb")
これを行う場合、io.open
がデフォルトで正確に返すものであるため、BufferedReader
で明示的にラップする必要はありません。
>>> type(f)
<type '_io.BufferedReader'>
詳細は its docs を参照してください。バッファリングを制御するbuffering
引数があります。
Python 3、open is io.open
では、2つのI/Oライブラリが1つにマージされています。io
がPython 2.6主に上位互換性のため。
buffering
argument を渡して、バッファリングの量をバイト単位で設定できます。
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
-バッファリングされた行。
Python2では、file
によって返されたopen
オブジェクトを使用する必要がある場合(または、たとえば変更できないモジュールルーチンによって提供される場合)、fileno()
によって取得されたファイル記述子を使用できます。ために io.FileIO
コンストラクター、次にio.FileIO
オブジェクトからio.BufferedReader
コンストラクタ。
したがって、サンプルコードは次のように書き換えることができます。
import sys
import io
srcfile = sys.argv[1]
with open(srcfile, 'rb') as f:
fio = io.FileIO(f.fileno())
fbuf = io.BufferedReader(fio)
print fbuf.read(20)