简体   繁体   English

Python编写二进制文件,字节

[英]Python writing binary files, bytes

Python 3. I'm using QT's file dialog widget to save PDFs downloaded from the internet. Python 3.我正在使用QT的文件对话框小部件来保存从互联网下载的PDF。 I've been reading the file using 'open', and attempting to write it using the file dialog widget. 我一直在使用'open'读取文件,并尝试使用文件对话框小部件来编写它。 However, I've been running into a"TypeError: '_io.BufferedReader' does not support the buffer interface" error. 但是,我一直遇到“TypeError:'_ io.BufferedReader'不支持缓冲区接口”错误。

Example code: 示例代码:

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

This logic works properly with text files when not using the 'b' designator, or when reading a file from the web, like with urllib or requests. 当不使用'b'指示符时,或者当从web读取文件时,如urllib或者请求,此逻辑适用于文本文件。 These are of the 'bytes' type, which I think I need to be opening the file as. 这些是“字节”类型,我认为我需要打开文件。 Instead, it's opening as a Buffered Reader. 相反,它作为缓冲读者开放。 I tried bytes(f1), but get "TypeError: 'bytes' object cannot be interpreted as an integer." 我尝试了字节(f1),但得到“TypeError:'bytes'对象不能被解释为整数。” Any ideaas? 有什么想法吗?

If your intent is to simply make a copy of the file, you could use shutil 如果您的目的是简单地制作文件的副本,则可以使用shutil

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

Or if you need to access byte by byte, similar to your structure, this works: 或者,如果您需要逐字节访问,类似于您的结构,这适用:

>>> 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

But byte by byte is potentially really slow . 但逐字节可能真的很慢

Or, if you want a buffer that will speed this up (without taking the risk of reading an unknown file size completely into memory): 或者,如果你想要一个能够加快速度的缓冲区(不会冒着将未知文件大小完全读入内存的风险):

>>> 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

With Python 2.7+ or 3.1+ you can also use this shortcut (rather than using two with blocks): 使用Python 2.7+或3.1+,您也可以使用此快捷方式(而不是使用两个with块):

with open('/tmp/fin.pdf','rb') as f1,open('/tmp/test.pdf','wb') as f2:
    ...

It really doesn't make sense to write a file in another file. 在另一个文件中写入文件真的没有意义。 What you want is to write the contents of f1 in f2. 你想要的是在f2中写入f1的内容。 You get the contents with f1.read(). 你用f1.read()获得内容。 So you have to do this: 所以你必须这样做:

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

learned from python cookbook python cookbook学到的

from functools import partial

with open(fpath, 'rb') as f, open(target_fpath, 'wb') as target_f: 
    for _bytes in iter(partial(f.read, 1024), ''):
        target_f.write(_bytes)

partial(f.read, 1024) returns a function, read the binary file 1024 bytes at every turn. partial(f.read, 1024)返回一个函数,每回合读取1024字节的二进制文件。 iter will end when meet a blank string '' . iter将结束时,遇到一个blank string ''

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM