Python读写二进制文件与struct模块使用指南
使用Python处理二进制数据时,可通过标准库中的struct模块实现高效的数据封包与解包。本文详细说明pack与unpack函数的参数用法、字节序控制符及常见格式代码,提供完整的文件读写代码示例,帮助开发者快速掌握二进制数据的序列化与反序列化操作,解决跨平台数据解析难题。
核心函数与数据格式映射
struct模块是Python标准库中用于将Python数据类型与定长字节流互相转换的工具,特别适合跨语言通信、文件格式解析或与C/C++程序交换数据。其核心在于通过格式化字符串(fmt)定义内存布局:
pack(fmt, v1, v2…):按指定格式将Python对象打包为字节串,返回字节流。unpack(fmt, buffer):按给定格式解析输入的字节流,返回包含原始值的元组。calcsize(fmt):计算该格式在内存中占用的字节数(含平台字节对齐)。常用于预分配缓冲区或跳过偏移量。
格式化字符串需严格对应数据类型,常见对照如下:b/B对应整型(有符号/无符号字符,1字节),i/I对应4字节整数,q/Q对应8字节长整型,f/d对应浮点数,s用于定长字符串,?表示布尔值。若需精确匹配其他平台的struct定义,可在开头添加对齐指令(如=默认主机顺序+无填充,@原生对齐)。对于网络传输或固定协议,强烈建议显式声明字节序:左尖括号<代表小端(Little-Endian,x86架构默认),右尖括号>代表大端(Big-Endian,网络传输常用)。
完整操作流程与代码示例
读写二进制文件的核心逻辑分为“写入编码”与“读取解码”两个阶段。为避免文件句柄泄漏与状态不一致,推荐始终使用上下文管理器管理文件对象。
第1步:写入二进制文件
目的:将Python对象按固定格式转换为字节序列并持久化到磁盘。
- 以写二进制模式打开目标文件(
wb)。 - 调用
struct.pack()生成字节流。 - 使用文件对象的
write()方法输出。
import struct
with open("data.bin", "wb") as f:
# 写入 4字节小端整数 (12345)
f.write(struct.pack("<i", 12345))
# 写入 8字节双精度浮点数 (3.14159)
f.write(struct.pack("<d", 3.14159))
# 写入 1字节布尔值 (True)
f.write(struct.pack("<?", True))
# 写入定长UTF-8字符串 ("hello",补空格至5字节)
s = "hello".encode("utf-8")
f.write(struct.pack("<5s", s))
# 写入定长字节数组 (20字节递增数据)
f.write(struct.pack("<20s", bytes(range(1, 21))))
第2步:读取并还原数据结构
目的:按写入时的完全一致的格式从字节流中反序列化数据。
- 以读二进制模式打开文件(
rb)。 - 根据格式长度调用
f.read(N)准确截取字节块。 - 使用
struct.unpack()解析,提取元组元素[0]。 - 对字符串字段执行解码,恢复可读文本。
with open("data.bin", "rb") as f:
int_val = struct.unpack("<i", f.read(4))[0]
float_val = struct.unpack("<d", f.read(8))[0]
bool_val = struct.unpack("<?", f.read(1))[0]
raw_str = struct.unpack("<5s", f.read(5))[0].decode("utf-8")
byte_arr = struct.unpack("<20s", f.read(20))[0]
print(f"整数: {int_val}") # 输出 12345
print(f"浮点: {float_val}") # 输出 3.14159
print(f"布尔: {bool_val}") # 输出 True
print(f"字符串: {raw_str}") # 输出 hello
print(f"字节数组: {byte_arr}") # 输出 b'\x01\x02...\x14'
关键语法与避坑指南
在处理底层数据时,几个易混淆的符号会直接影响解析结果:
- 前缀
b:直接定义字节字面量(如b'hello'),无需经过编码过程。Python 3 中所有二进制操作均基于bytes类型,字符串与字节互转必须显式指定编码(.encode()/.decode())。 - 字节序标识
</>:决定多字节数值(如 int, double)在内存中的高低位排列。未显式声明时,系统可能采用本机默认端序,导致跨平台读取乱码。强制统一端序是工业级数据交换的底线。 - 字符串格式
s的长度限制:格式中的数字(如5s)代表严格预留空间。如果写入字符串超过该长度,pack会抛出异常;若不足,会以空字符(\x00)补齐。读取后务必按需截断或解码清理尾零。
总结
以上就是使用Python结合struct模块进行二进制文件读写与数据封包的详细内容,更多关于Python基础文件操作与跨语言数据交互的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













