13

Python 3. QT のファイル ダイアログ ウィジェットを使用して、インターネットからダウンロードした PDF を保存しています。「開く」を使用してファイルを読み取り、ファイル ダイアログ ウィジェットを使用して書き込みを試みました。ただし、「TypeError: '_io.BufferedReader' はバッファー インターフェイスをサポートしていません」というエラーが発生しました。

コード例:

with open('file_to_read.pdf', 'rb') as f1: 
    with open('file_to_save.pdf', 'wb') as f2:
        f2.write(f1)

このロジックは、「b」指定子を使用していない場合、または urllib やリクエストのように Web からファイルを読み取る場合に、テキスト ファイルで適切に機能します。これらは「バイト」タイプであり、ファイルを開く必要があると思います。代わりに、Buffered Reader として開いています。bytes(f1) を試しましたが、「TypeError: 'bytes' オブジェクトを整数として解釈できません。」何かアイデアはありますか?

4

3 に答える 3

17

ファイルのコピーを作成するだけの場合は、shutilを使用できます。

>>> import shutil
>>> shutil.copyfile('file_to_read.pdf','file_to_save.pdf')

または、構造と同様に、バイトごとにアクセスする必要がある場合、これは機能します。

>>> with open('/tmp/fin.pdf','rb') as f1:
...    with open('/tmp/test.pdf','wb') as f2:
...       while True:
...          b=f1.read(1)
...          if b: 
...             # process b if this is your intent   
...             n=f2.write(b)
...          else: break

しかし、バイトごとに実行すると、潜在的に非常に遅くなります。

または、これを高速化するバッファーが必要な場合 (未知のファイル サイズを完全にメモリに読み込むリスクを冒すことなく):

>>> with open('/tmp/fin.pdf','rb') as f1:
...    with open('/tmp/test.pdf','wb') as f2:
...       while True:
...          buf=f1.read(1024)
...          if buf: 
...              for byte in buf:
...                 pass    # process the bytes if this is what you want
...                         # make sure your changes are in buf
...              n=f2.write(buf)
...          else:
...              break

withPython 2.7+ または 3.1+ では、(2 つのブロックを使用するのではなく) 次のショートカットを使用することもできます。

with open('/tmp/fin.pdf','rb') as f1,open('/tmp/test.pdf','wb') as f2:
    ...
于 2013-05-19T03:18:52.070 に答える