python - 如何用 Python 编写原始二进制数据?

标签 python codec string

我有一个 Python 程序,可以将数据存储和写入文件。数据是原始二进制数据,内部存储为 str .我正在通过 utf-8 编解码器将其写出来。但是,我得到 UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 25: character maps to <undefined>cp1252.py文件。

在我看来,Python 正在尝试使用默认代码页解释数据。但它没有默认代码页。这就是我使用 str 的原因, 不是 unicode .

我想我的问题是:

  • 如何在 Python 中表示内存中的原始二进制数据?
  • 当我通过编解码器写出原始二进制数据时,我该如何对其进行编码/取消编码?

最佳答案

注意:这是为 Python 2.x 编写的。不确定是否适用于 3.x。

您对内存中的原始二进制数据使用 str 是正确的。
[如果您使用的是 Python 2.6+,最好使用 bytes,它在 2.6+ 中只是 str 的别名,但可以更好地表达您的意图,如果有一天你将代码移植到 Python 3。]

正如其他人所说,通过编解码器写入二进制数据很奇怪。写入编解码器采用 unicode 并将输出字节 到文件中。你试图倒着做,因此我们对你的意图感到困惑......

[而且您对错误的诊断看起来是正确的:由于编解码器需要 unicode,Python 正在使用系统的默认编码将您的 str 解码为 un​​icode,这令人窒息。]

您想在输出文件中看到什么?

  • 如果文件应按原样包含二进制数据:

    那么你一定不能通过编解码器发送它;你必须写 直接到文件。编解码器编码一切并且只能 发出有效的 unicode 编码(在您的情况下,有效的 UTF-8)。 没有输入可以让它发出任意 字节序列!

    • 如果您需要 UTF-8 和原始二进制数据的混合,您 应该直接打开文件,并混合写入 some_data 使用 some_text.encode('utf8')...

    但是请注意,将 UTF-8 与原始任意数据混合非常 糟糕的设计,因为这样的文件处理起来很不方便 和!理解 unicode 的工具会阻塞二进制文件 数据,让您无法方便地查看(更不用说 修改)文件。

  • 如果你想要一个友好的任意字节的表示 统一码:

    data.encode('base64') 传递给编解码器。 Base64 只产生 干净的 ascii(字母、数字和一些标点符号)所以它 可以清楚地嵌入到任何东西中,它在人们看来显然是 二进制数据,它相当紧凑(略高于 33% 开销)。

    附言您可能会注意到 data.encode('base64') 很奇怪。

    • .encode() 应该采用 unicode 但我给它一个 字符串?! Python 有几个伪编解码器可以转换 str->str 例如“base64”和“zlib”。

    • .encode() 总是返回一个 str 但你会把它输入一个编解码器 期待 unicode?!在这种情况下,它只会包含干净的 ascii,所以没关系。你可以明确地写 data.encode('base64').encode('utf8') 如果让你觉得 更好。

  • 如果您需要从任意字节到 unicode 的 1:1 映射:

    data.decode('latin1') 传递给编解码器。 latin1 map 字节 0-255 到 unicode 字符 0-255,这有点优雅。

    编解码器当然会对您的字符进行编码 - 128-255 是 在 UTF-8 中编码为 2 或 3 个字节(令人惊讶的是,平均 开销是 50%,比 base64 多!)。这完全杀死了 具有 1:1 映射的“优雅”。

    另请注意,unicode 字符 0-255 包括讨厌的字符 不可见/控制字符(换行符、换页符、软连字符等) 使您的二进制数据在文本编辑器中查看很烦人。

    考虑到这些缺点,我不推荐latin1,除非 你完全明白你为什么想要它。
    我只是提到它是另一种“自然”编码 记住。

关于python - 如何用 Python 编写原始二进制数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2611205/

相关文章:

python - Pycharm/IntelliJ 显示 pytest 的覆盖率为 0%,即使已生成覆盖率

c++ - 如何加速OpenH264的解码器

c# - 弹性视频编解码器(断电)

regex - 在Dart中获取以符号开头的单词

python - 如何使用 Scrapy 抓取新链接

python - np 数组之间的欧氏距离

python - 返回特定字符出现次数最多的字符串

c - 如何使用 libvlc 检索编解码器信息?

ruby-on-rails - 仅显示 Rails 中字符串的前 x 个单词

ruby - string.include 的奇怪行为?在 ruby