Reader

【Python】二进制字节流处理库struct

| dtysky|一个行者的轨迹 | Default

struct类用于打包和解包二进制字节流,对于二进制数据的处理至关重要。

pack

pack方法用于将数据打包成字节流,数据可以是数字、字符串、数组,其使用方法为:

import struct
struct.pack(fmt, data)

fmt是格式化的格式,data为数据,fmt的规则为[order][format],order为字节顺序,比如小端LE、大端BE等,format就是字节的格式了,可以是字节、整形、浮点数等,比如:

In[13]: struct.pack(">II", *[1, 2])
Out[13]: '\x00\x00\x00\x01\x00\x00\x00\x02'
In[14]: struct.pack("<II", *[1, 2])
Out[14]: '\x01\x00\x00\x00\x02\x00\x00\x00'

以下是详细规则:

字节顺序

Character Byte order Size Alignment
@ native native native
= native standard none
< little-endian standard none
> big-endian standard none
! network (= big-endian) standard none

格式

Format C Type Python type Standard size Notes
x pad byte no value
c char string of length 1 1
b signed char integer 1 (3)
B unsigned char integer 1 (3)
? _Bool bool 1 (1)
h short integer 2 (3)
H unsigned short integer 2 (3)
i int integer 4 (3)
I unsigned int integer 4 (3)
l long integer 4 (3)
L unsigned long integer 4 (3)
q long long integer 8 (2), (3)
Q unsigned long long integer 8 (2), (3)
f float float 4 (4)
d double float 8 (4)
s char[] string
p char[] string
P void * integer (5), (3)

注意

首先要注意的是大端小端的问题,这个在上面的例子已经有所体现,如果不加order标志,默认使用的是@这个order。
其次,使用时如果相对数组使用,必须要加上不定参数标志*

unpack

用于解包二进制数据,基本和pack的用法一致,不过是逆运算,fmt的格式和pack一模一样,第二个参数为二进制字节流,返回一个由结果构成的元祖。

In[15]: struct.unpack("<II", '\x01\x00\x00\x00\x02\x00\x00\x00')
Out[15]: (1, 2)

效率

测试表明,打包和解包的性能的确会随着数据量的大小而发生变化。这个变化似乎并不是线性的,在一定数据量以下时,性能并不会成为瓶颈,但当数据量超过某个数量级时,性能会极速恶化,这一点需要注意。