Python 二进制文件读写实战:struct 模块与格式化字符串详解

桃夭
桃夭
发布时间:2026-10-12| 2人浏览过
原创

本文详解如何利用 Python 内置 struct 模块进行结构化二进制数据的打包与解包。涵盖格式化字符串编写、字节序与对齐控制,以及 rb/wb 文件模式的操作细节。提供标准代码示例与常见报错排查方案,帮助开发者高效处理底层数据流,彻底规避文本模式导致的截断与跨平台换行符转换问题。

为什么需要专用二进制处理模式

Python 原生数据类型在内存中以特定结构存储,当需要将其持久化或与 C/C++ 结构体交互时,必须转换为定长字节流。直接使用文本模式(r/w)打开文件会触发操作系统的隐式编码转换,导致特定字节被误判为结束符或发生长度偏移。使用 struct 模块配合二进制文件模式(rb/wb)可实现精确到字节的无损读写。

第1步:定义格式字符串并打包数据

目的:将 Python 基本类型按固定规则压缩为连续的二进制字节序列。

入口:导入 import struct。

动作:调用 struct.pack(fmt, values),传入格式字符串与对应参数。格式字符串由数字前缀与类型字符组成,如 5s 表示 5 字节字符串,i 表示 4 字节整数。注意:原始草稿中使用 'i' 打包浮点数会导致截断或异常,此处已修正为 'd'(双精度)或 'f'(单精度)以兼容小数。

重要参数:fmt 需严格匹配后续 unpack 的顺序与长度。

完成状态:函数返回一个仅包含原始字节(不可见字符)的 bytes 对象,无额外转义标记。

import struct

# 准备混合类型数据
name = b"hello"
count = 2
value = 45.123

# 打包:'5sif' 依次对应 5字节字符串、整型、单精度浮点
data_bytes = struct.pack("5sif", name, count, value)
print(data_bytes)  # 输出形如 b'hello\x00\x02\x00\x00@<...' 的字节流

第2步:以 wb/rb 模式执行文件读写

目的:绕过 Python 默认的文本缓冲与字符集检测,直接对磁盘扇区进行字节级操作。

入口:内置 open() 函数。

动作:使用 open(filepath, "wb") 写入,open(filepath, "rb") 读取。

风险提示:"wb" 模式会在打开瞬间清空目标文件原有内容。若用于增量保存或归档,请务必先确认文件权限,或对源数据进行备份,防止不可逆覆盖。

完成状态:成功关闭文件句柄后,磁盘文件大小与打包后的字节数完全一致。

# 写入二进制文件
with open("sample.bin", "wb") as binfile:
    binfile.write(data_bytes)

# 读取二进制文件
with open("sample.bin", "rb") as binfile:
    raw_data = binfile.read()

第3步:读取字节流并解包还原

目的:将磁盘读出的原始字节按原规则还原为可读的 Python 变量。

入口:确保已通过 read() 获取完整字节块。

动作:调用 struct.unpack(fmt, raw_data)。该函数强制返回一个元组(tuple)。若只解包单个值,必须通过切片或逗号语法提取:(val,) = struct.unpack(...) 或 val, = struct.unpack(...)。

重要参数:fmt 必须与打包时的格式严格对称。

完成状态:变量类型恢复为初始设定,数值精确匹配。

# 解包还原
n, c, v = struct.unpack("5sif", raw_data)
print(n, c, v)  # 输出: b'hello' 2 45.123

核心参数对照表

1. 格式化字符(Format Codes)

FormatC TypePython字节数
xpad byteno value1
ccharstring of length 11
bsigned charinteger1
Bunsigned charinteger1
?_Boolbool1
hshortinteger2
Hunsigned shortinteger2
iintinteger4
Iunsigned intinteger or long4
llonginteger4
Lunsigned longlong4
qlong longlong8
Qunsigned long longlong8
ffloatfloat4
ddoublefloat8
schar[]string变长

2. 字节序与对齐前缀(放在 fmt 首位)

CharacterByte orderSize and alignment
@nativeNative padding, 凑够 4 个字节对齐
=nativeStandard size, 按原字节数无填充
<little-endianStandard size, 小端字节序
>big-endianStandard size, 大端字节序
!network (= big-endian)Standard size, 网络字节序

使用方法:将前缀拼接至格式串开头,例如 <5sif 表示采用小端模式、无自然对齐填充的字符串-整数-浮点组合。

常见报错与排错指南

  • EOFError / 读取截断:若在 Windows 下使用文本模式 r 读取含有 0x1A(ASCII 控制字符 ZOW)的数据,解析器会提前判定为文件结束。切换至 rb 后可恢复完整读取。
  • 长度不一致:Windows 文本模式写入时会隐式将 0x0A(LF)扩展为 0x0D 0x0A(CRLF),导致文件体积增加。二进制模式 wb/rb 保持绝对原始字节,不会发生此类扩写。Linux/macOS 默认不转换换行符,跨平台交换数据时务必统一使用二进制模式。
  • Unpack 返回元组未解包:直接赋值 a = struct.unpack("i", b) 会得到 (12,)。正确做法是使用逗号拆分 a, = struct.unpack("i", b) 或直接索引 a[0]。

简要总结

通过 struct 模块的格式字符串映射与二进制 I/O 结合,Python 能够安全、高效地替代底层语言处理定长数据包。掌握 pack/unpack 的对称性、字节序前缀的选择以及 rb/wb 的物理读写特性,即可彻底解决文件损坏、数据错位与跨平台兼容性难题。以上就是使用 Python 进行二进制文件读写的详细内容,更多关于 Python 基础操作与文件处理的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。