Python编写二进制文件,字节

Posted

技术标签:

【中文标题】Python编写二进制文件,字节【英文标题】:Python writing binary files, bytes 【发布时间】:2013-05-13 21:43:52 【问题描述】:

Python 3。我正在使用 QT 的文件对话框小部件来保存从 Internet 下载的 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 或请求。这些是“字节”类型,我认为我需要打开文件。相反,它作为缓冲阅读器打开。我尝试了字节(f1),但得到“TypeError:'bytes'对象不能被解释为整数。”有什么想法吗?

【问题讨论】:

试试吧 - data = list(f1.read())f2.write(data) 'list' 显然也不支持缓冲接口。 【参考方案1】:

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)返回一个函数,每次读取二进制文件1024字节。 iter 将在遇到 blank string '' 时结束。

【讨论】:

我得到了这个代码的无限循环,可能EOF没有被正确识别。 @dawg 的回答按预期工作正常。学习只是进一步阅读,使用 `b'' ` 作为 EOF ...【参考方案2】:

如果您的意图是简单地复制文件,您可以使用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

对于 Python 2.7+ 或 3.1+,您还可以使用此快捷方式(而不是使用两个 with 块):

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

【讨论】:

谢谢您 - 您的第二个和第三个解决方案都有效。 (由于 QT 的保存对话框的工作方式,不能使用 copyfile) 简单地使用 bufferedReader 上的 .read() 来转换为字节似乎也可以——我想我已经尝试过了。从你的例子中学到了一些新东西。 请注意,变量名bytes 可能与Python 3.x 中表示二进制数据的Python 内置类型bytes 冲突! (在 Python 2.7 中它只是 str 的别名) @minmaxavg:你说得对,我一有机会就会改变。谢谢! shutil.copyfileobj() wraps the while-loop。看看它是如何在shutil.copyfile() 中使用的。要复制文件元数据,您可以使用shutil.copy2()。如果你想要to access a file as a buffer; you could use mmap (it works even if the whole file doesn't fit in memory) @minmaxavg: 1- 甚至我的手机也是 64 位的。 2- 是的,Windows 上有mmap。阅读 mmap 模块的官方 Python 文档。【参考方案3】:

将一个文件写入另一个文件确实没有意义。你想要的是将f1的内容写入f2。您可以使用 f1.read() 获取内容。所以你必须这样做:

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

【讨论】:

这是当前解决方案的样子。 虽然这有效,但整个文件在写入之前被读入内存——对内存不太友好。如Python中所述docsit’s your problem if the file is twice as large as your machine’s memory

以上是关于Python编写二进制文件,字节的主要内容,如果未能解决你的问题,请参考以下文章

如何编写带有字节嵌入消息的原型文件

python读写二进制文件(读写字节数据)

Python:如何比较两个二进制文件?

如何在 C++ 或 Python 中快速将二进制文件划分为 6 字节块? [关闭]

从文件中读取和存储任意字节长度的整数

Python学习笔记015——文件file的常规操作之二(二进制文件)