我有一个 Python 程序,可以存储数据并将数据写入文件。数据是原始二进制数据,内部存储为str
。我正在通过 utf-8 编解码器将其写出来。但是,我得到UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 25: character maps to <undefined>
in the cp1252.py
file.
在我看来,Python 正在尝试使用默认代码页解释数据。但事实并非如此have默认代码页。这就是我使用的原因str
, not unicode
.
我想我的问题是:
- 如何在 Python 中表示内存中的原始二进制数据?
- 当我通过编解码器写入原始二进制数据时,如何对其进行编码/取消编码?
注意:这是为 Python 2.x 编写的。不确定是否适用于 3.x。
您的使用str
对于内存中的原始二进制数据是正确的。
[如果您使用的是Python 2.6+,则更好使用bytes
在 2.6+ 中它只是一个别名str
但更好地表达了您的意图,并且如果有一天您将代码移植到 Python 3,将会有所帮助。]
正如其他人指出的那样,通过编解码器写入二进制数据很奇怪。写编解码器采用 unicode and 输出字节到文件中。你试图倒退,因此我们对你的意图感到困惑......
[并且您对错误的诊断看起来是正确的:由于编解码器需要 unicode,Python 正在使用系统的默认编码将您的 str 解码为 unicode,这令人窒息。]
您想在输出文件中看到什么?
-
如果文件应按原样包含二进制数据:
那么你一定不能通过编解码器发送它;你必须写它
直接到文件。编解码器编码一切并且只能
发出有效的 unicode 编码(在您的情况下,有效的 UTF-8)。
没有任何输入可以让它发出任意信号
字节序列!
- 如果您需要一个mixtureUTF-8 和原始二进制数据,您
应该直接打开文件,并混合写入
some_data
with some_text.encode('utf8')
...
但请注意,将 UTF-8 与原始任意数据混合是非常危险的。
设计不好,因为这样的文件处理起来很不方便
和!理解 unicode 的工具会因二进制文件而卡住
数据,让您甚至无法方便地查看(更不用说
修改)文件。
-
如果您想要任意字节的友好表示
统一码:
Pass data.encode('base64')
到编解码器。 Base64 只产生
干净的ascii(字母、数字和一点标点符号)所以它
可以清楚地嵌入到任何东西中,它在人们看来显然是
二进制数据,而且相当紧凑(略高于 33%
高架)。
附:你可能会注意到data.encode('base64')
很奇怪。
.encode()
应该采用 unicode 但我给它一个
细绳?! Python 有几个伪编解码器可以将 str->str 转换
例如“base64”和“zlib”。
.encode()
总是返回一个 str 但你会将其输入编解码器
期待统一码?!在这种情况下,它只会包含干净的
ascii,所以没关系。你可以明确地写data.encode('base64').encode('utf8')
如果它让你感觉
更好的。
-
如果您需要从任意字节到 unicode 的 1:1 映射:
Pass data.decode('latin1')
到编解码器。latin1
地图
字节 0-255 到 unicode 字符 0-255,这有点优雅。
当然,编解码器会对您的字符进行编码 - 128-255 是
以 UTF-8 编码为 2 或 3 个字节(令人惊讶的是,平均
开销是 50%,比 base64 还多!)。这相当杀死
1:1 映射的“优雅”。
另请注意,unicode 字符 0-255 包括令人讨厌的字符
不可见/控制字符(换行符、换页符、软连字符等)
使您的二进制数据在文本编辑器中查看起来很烦人。
考虑到这些缺点,我不推荐拉丁1除非
你完全明白为什么你想要它。
我只是将其称为另一种“自然”编码
去提醒。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)