Python struct模块二进制文件读写与字节序详解
本文详细介绍Python中struct模块处理二进制文件的方法。通过pack和unpack函数实现数据封装与解析,涵盖浮点数、双精度及整型的转换示例。重点解析大端、小端及网络字节序的对齐方式,帮助开发者高效处理C/C++结构体数据交互。
首先,需要导入处理二进制数据的必要模块:import struct
该模块提供了几个核心功能函数,用于处理数据与字节流之间的转换。
# 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流) pack(fmt, v1, v2, ...) # 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple unpack(fmt, string) # 计算给定的格式(fmt)占用多少字节的内存 calcsize(fmt)
假设需要读取一个名为filename的文件,该文件存储了形状为[100,1025]的浮点数数据。可以通过以下步骤实现读取:
import numpy as np
import struct
# 加载测试数据
f = open('filename','rb')
# 102500为文档中包含的数字个数,而一个浮点数占4个字节
data_raw = struct.unpack('f'*102500,f.read(4*102500))
f.close()
verify_data = np.asarray(verify_data_raw).reshape(-1,1025)
类似地,若需将二进制数据转换为double类型,可采用如下方式处理:
import numpy as np
import struct
f = open('data8.dat','rb')
d_str = f.read()
f.close()
d_len = len(d_str)
d_len2 = d_len//8
#有时还需考虑字节顺序,如为big-endian,则以上语句改为 data = struct.unpack('>'+str(d_len/4)+'f',d_str)
data = struct.unpack(d_len2*'d',d_str)
需要注意的是,格式字符串前的乘数必须为整数类型(int),例如int*'d'。如果误用浮点数相乘,程序将抛出'can't multiply sequence by non-int of type 'float''的错误。
关于函数的具体参数和用法细节,建议查阅struct官方文档以获取完整信息。
以下是fmt格式字符串的常见表示方法汇总:
| FORMAT | PYTHON TYPE | STANDARD SIZE |
| x | no value | |
| c | string of length 1 | 1 |
| b | integer | 1 |
| B | integer | 1 |
| ? | bool | 1 |
| h | integer | 2 |
| H | integer | 2 |
| i | integer | 4 |
| I | integer | 4 |
| l | integer | 4 |
| L | integer | 4 |
| q | integer | 8 |
| Q | integer | 8 |
| f | float | 4 |
| d | float | 8 |
| s | string | |
| p | string | |
| P | integer |
为了与C语言中的结构体进行数据交换,必须考虑编译器可能采用的字节对齐机制。在通常以4个字节为单位的32位系统中,struct模块会根据本地机器的字节顺序进行转换。可以通过格式字符串中的第一个字符来指定对齐方式,具体定义如下:
| CHARACTER | BYTE ORDER | SIZE | ALIGNMENT |
| @ | native | native | native |
| = | native | standard | none |
| < | little-endian | standard | none |
| > | big-endian | standard | none |
| ! | network (= big-endian) | standard | none |
< 表示小端模式(Little-Endian),即低位字节存储在内存的低地址端(栈顶),高位字节存储在高地址端(栈底)。
> 表示大端模式(Big-Endian),即高位字节存储在内存的低地址端,低位字节存储在高地址端。
! 表示网络字节序:TCP/IP协议栈将字节序定义为Big-Endian,因此网络通信中通常使用这种字节序标准。
以上内容涵盖了Python struct模块处理二进制数据的核心要点,希望能为读者在文件读写和数据交互方面提供帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













