有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体.
struct模块中最重要的三个函数是pack(), unpack(), calcsize()
pack(fmt, v1, v2, ...) 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
unpack(fmt, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
calcsize(fmt) 计算给定的格式(fmt)占用多少字节的内存
struct中支持的格式如下表:
FormatC TypePython字节数
x
pad byte
no value
1
c
char
string 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 or long
4
l
long
integer
4
L
unsigned long
long
4
q
long long
long
8
Q
unsigned long long
long
8
f
float
float
4
d
double
float
8
s
char[]
string
1
p
char[]
string
1
P
void *
long
注1.q和Q只在机器支持64位操作时有意思
注2.每个格式前可以有一个数字,表示个数
注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串
注4.P用来转换一个指针,其长度和机器字长相关
注5.最后一个可以用来表示指针类型的,占4个字节为了同c中的结构体交换数据,还要考虑有的c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:
CharacterByte orderSize and alignment
@
native
native 凑够4个字节
=
native
standard 按原字节数
<
little-endian
standard 按原字节数
>
big-endian
standard 按原字节数
!
network (= big-endian)
standard 按原字节数
1 importstruct2
3 #定义数据
4 a = "hello"
5 b = "world!"
6 c = 20
7 d = 42.56
8
9 #打包
10 binStr = struct.pack("5s6sif", a, b, c, d)11 printlen(binStr)12 binStr2 = struct.pack("i", c)13
14 #解包
15 e, f, g, h = struct.unpack("5s6sif", binStr)16 printe, f, g, h17
18 #注意unpack返回的是tuple,如果不按规定格式书写,则返回值将改变类型
19 i, = struct.unpack("i", c)20 printi21 i = struct.unpack("i", c)22 printi23
24 #计算转换字节长度
25 print struct.calcsize("5s6sif")