Python中对二进制文件编码
JSON是一种简单方便的数据交换协议,但一般情况下JSON只能对字符串,整型和浮点型数据编码传输,一般的文本文件可以通转换为过字符串传输,而二进制的文件则不能直接传输,在这种情况下就需要对二进制文件进行编码,转换成适合JSON传输的格式,在这里采用base64的编码。
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据。
转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6(因为)个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
Python 对二进制文件Base64编码
Python的base54
库可以直接对二进制文件编码和解码,一个简单的例子如下:
import base64
fin = open("platinum_firebird.out", "rb")
fout = open("based.txt", "wb")
base64.encode(fin, fout)
fin.close()
fout.close()
fin = open("based.txt", "rb")
fout = open("out.out", "wb")
base64.decode(fin, fout)
fin.close()
fout.close()
base64
中的encode
和decode
函数直接可以对文件进行编码和解码。
文件编码为字符串
在通过JSON传输时,需要将文件转化为字符串str
,需要用到b64encode
和b64decode
两个函数。
import base64
import json
with open("platinum_firebird.out", "rb") as fin:
coded = base64.b64encode(fin.read()).decode()
send = json.dumps({"file": coded})
receive = json.loads(send)['file']
decoded = base64.b64decode(receive)
with open("out.out", "wb") as fout:
fout.write(decoded)
需要说明的是base64.b64encode
的结果是bytes
类型,bytes
是不能直接被json
序列化的,需要通过decode
转化为str
类型,这个主要是python3对bytes
和str
区别对待造成的。
通过上面的例子,我们已经可以实现文件的JSON的传输。
GZIP压缩
这里举例用的文件大小是482396, base64编码并JSON化之后是643208,可以看到base64之后文件变大了,这是意料之中的,为了节省网络带宽,我们可以对文件压缩之后再编码,举例程序如下:
import base64
import json
import gzip
with open("platinum_firebird.out", "rb") as fin:
coded = base64.b64encode(gzip.compress(fin.read())).decode()
send = json.dumps({"file": coded})
print(len(send))
receive = json.loads(send)['file']
decoded = gzip.decompress(base64.b64decode(receive))
with open("out.out", "wb") as fout:
fout.write(decoded)
压缩之后编码最终JSON化之后字符串减小到115508, 只有原来的1/5左右大小,可以看到,压缩效果还是非常明显的,不过这个和原始文件的内容有关。
原始文件大小 | 直接编码结果 | 压缩之后编码结果 |
---|---|---|
482396 | 643208 | 115508 |
最后更新于 2017-06-06 09:29:11 并被添加「python json」标签,已有 2733 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。