首页 > 编程笔记 > Python笔记 阅读:5

Python struct模块读写二进制数据(附带实例)

有的时候需要用 Python 处理二进制数据,如存取文件或 socket 通信时,可以使用 Python 的 struct 模块完成,用 struct 模块处理 C语言中的结构体。

结构体在 C语言中定义了一种结构,包含不同类型的数据(int、char、bool 等),可方便对某一结构对象进行处理。在网络通信中,传输的数据大多是以二进制流(Binary Data)的形式存在的,当传输字符串时,不必担心太多的问题,当传输诸如 int、char 之类的基本数据时,就需要有一种机制,先将某些特定的结构体类型打包成二进制流的字符串,再通过网络传输,接收端通过某种机制解包还原出原始的结构体数据。

Python 中的 struct 模块就提供了这样的机制。该模块的主要作用是对 Python 基本数据类型与用 Python 字符串格式表示的 C语言 struct 类型进行转换。

struct 模块中最重要的函数为 pack()、unpack() 和 calcsize():
测试代码为:
>>> import struct
>>> import binascii
>>> p_data = struct.pack('I4s', *data)
>>> print(binascii.hexlify(p_data))
b'01000000061626364'
>>> unp_data = struct.unpack('I4s',p_data)
>>> type(unp_data)
<class 'tuple'>
>>> print(unp_data)
(1, b'abcd')
在测试代码中,首先定义了一个元组,包含 int、bytes 两种数据类型。

注意,格式化字符串的值在 Python3 中的类型是 bytes 类型,需要在 bytes 类型前面加上一个 b 后,再通过 struct 的 pack 打包,并制定 format'I4s' 的规则,I 表示 int,4s 表示三个字符长度的字符串。

由输出结果可知,data 被 pack 之后,首先转化为一段二进制字节串,然后通过 struct 的 unpack 对打包的二进制数据进行解包,将字节串再转换回元组。

定义 format 可以参照官方 API 提供的对照表,如下表所示:

表:官方 API 提供的对照表
format C Type Python Type Seanrdard Size
x pad byte no value  
c char bytes of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
n size_t integer  
N size_t integer  
e (7) float 2
f float float 4
d double float 8
s char[] bytes  
P char[] bytes  
p void * integer  

struct.calcsize 用于计算格式字符串对应的长度,如 struct.calcsize('ii') 返回 8,因为两个 int 数据类型占用的长度是 8 个字节,代码为:
>>> print(struct.calcsize('i'))
4
>>> print(struct.calcsize('ii'))
8
>>> print(struct.calcsize('s'))
1
>>> print(struct.calcsize('is'))
5
>>> print(struct.calcsize('d'))
8
>>> print(struct.calcsize('f'))
4

相关文章