我新建一个文件,并以二进制形式往里写入大写字母 A 的 ASCII 所对应的 01000001 ,按理说,把文件以文本格式打开,显示的应该是 A ,占用一个字符,但结果显示是 01000001 ,占用 8 个字符
fd = open('./a.test', 'xb')
fd.write(b'01000001')
为什么呢?是因为缺少 EOF 之类控制字符吗,在写入进文件时被 IDE 直接优化成文本吗?又或者打开时被文本软件优化了?
对于一个二进制文件,以文本格式打开,文本软件会把二进制 bit 按照每 8bit 算作一个字符对照 ascii 编码表翻译,而 ascii 最大值是 01111111 ,也就是说如果有 8bit 大于这个数,如 10111111 ,因为找不到参照,文本软件就会显示乱码是吗?乱码字符对应的那个图案是从哪找的呢?
还有如果二进制文件的大小不是 8bit 整数倍,假如最后剩下 3bit ,文本软件也会显示乱码吗?
所以有了 base64 ,使用 6bit 全部占满的编码方式重新编码二进制文件,保证不会出现乱码,然后在网页和邮件中传输是吗?但实际没必要,直接在网络中使用原始二进制传输也可以,只是网页和邮件的协议要求而已,对吗?
1
shadowCheng 2021-12-21 11:04:49 +08:00
b'01000001'指的只是 byte 类型'01000001'字符串
|
2
debuggerx 2021-12-21 11:06:40 +08:00
L1 正解,正确的写法应该是:
fd.write(bytes([0b01000001])) |
3
qianxings 2021-12-21 11:10:47 +08:00
https://docs.python.org/zh-cn/3/reference/lexical_analysis.html#integer-literals
fd = open('./a.test', 'xb') fd.write(b'0b01000001') |
4
xylxAdai 2021-12-21 11:20:51 +08:00
。。。b 关键字是 byte 。。不是 bit 。
|
5
hsfzxjy 2021-12-21 11:49:21 +08:00 via Android
> 多谢大家,那我下面关于乱码的理解对吗?
不对,你只能写入 8bit 的整数倍,也就是完整的 byte 。 |
6
sujin190 2021-12-21 12:01:54 +08:00
似乎有点本末倒置了啊,所有文件保存的、网络传输的都是二进制,并没有啥区别,
为啥有二进制文件和文本文件,这个其实是用你的查看方式决定的,你用文本查看就是文本文件,文本文件有不同编码方式,比如 gbk ,utf8 之类的,你打开文件的时候就已经选定了一种解码方式,并不是文件告诉你应该用啥解码,所以才会有乱码问题,乱码图案自然从你选定的解码方式里找啊 关于 base64 其实是邮件和网页已经首先选定了文本型 utf-8 编码换行分隔,如果你直接在里边放二进制数据,那么二进制数据自身就会影响解析,比如二进制里按文本解析就有换行符啊,这时就要解析出错了,本质来说在编码的分层结构中,网页和邮件是用的是规则匹配来解析数据,那么首先你网页邮件里保存的数据就必须保证不能有符合网页邮件解析规则的数据,所以才有了 base64 来把二进制数据编码成肯定不会匹配网页解析规则的文本数据,而像 grpc 这种用的就是预定义结构解析,所以内部保存的数据不可能影响结构解析过程,所以也就不需要再编码 |