pickle.dump写入文件出现非预期额外二进制数据的原因及解决方法
问题解答
额外数据的来源
你观察到的冗余内容是pickle序列化协议自带的格式元数据,不属于你主动写入的数组二进制内容。pickle.dump()的设计目标是序列化Python对象,而非裸写二进制流:无论传入的参数是字节、数值、列表还是自定义类实例,它都会按照pickle协议规范,为每个待存储的对象追加协议版本标记、对象类型标识、长度字段、结束符等元信息,确保后续可以通过pickle.load()完整还原出原始Python对象。你代码中两次调用pickle.dump(),相当于连续序列化了两个独立的bytes类型对象,每个对象的前后都会生成对应的格式标记,就是你在十六进制编辑器中看到的额外内容。
移除冗余数据的方法
如果你不需要依赖pickle做反序列化,只想把原始二进制字节完整写入文件、不带任何额外内容,不要使用pickle模块,直接调用文件对象的write()方法写入原始字节即可,修正后的代码如下:
import numpy as np save_file = open('test.rdb', 'wb') # 写入第一个int类型数组的原始字节 save_data = np.array([1, 2, 3]) save_file.write(save_data.tobytes()) # 写入第二个float类型数组的原始字节 save_data = np.array([1.0, 2.0, 3.0]) save_file.write(save_data.tobytes()) save_file.close() # 读取验证 read_file = open('test.rdb', 'rb') data = read_file.read() print(data)
用这种方式生成的文件只会包含你写入的原始数组二进制内容,不存在任何额外标记。
注意:裸写二进制的方式不会存储数组的dtype、形状、长度等元信息,后续读取时需要自行记录每段字节对应的数据类型和长度,才能通过
np.frombuffer()正确还原数组。如果需要便捷存取numpy数组,推荐使用numpy原生的.npy/.npz格式,无需手动维护元信息,存储效率也高于pickle。
内容的提问来源于stack exchange,提问作者JongTak Hong
相关产品推荐
相关产品推荐

