Python/struct

有的时候需要用Python处理二进制数据,比如,存取文件、socket操作。可以使用Python的struct模块来完成。

struct模块中最重要的三个函数是pack(), unpack(), calcsize()

  • pack(fmt, v1, v2, ...) 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
  • unpack(fmt, string) 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
  • calcsize(fmt) 计算给定的格式(fmt)占用多少字节的内存

格式描述

struct中支持的格式如下表:

FormatC 语言数据类型Python字节数
xpad byteno value1
ccharstring of length 11
bsigned charinteger1
Bunsigned charinteger1
?_Boolbool1
hshortinteger2
Hunsigned shortinteger2
iintinteger4
Iunsigned intinteger / long4
llonginteger4
Lunsigned longlong4
qlong longlong8
Qunsigned long longlong8
ffloatfloat4
ddoublefloat8
schar[]string1(表示一定长度的字符串,4s表示长度为4的字符串)
pchar[]string1 (表示的是pascal字符串)
Pvoid *long和机器字长相关

每个格式前可以有一个数字,表示个数。

可以用格式中的第一个字符来改变对齐方式.定义如下:

字符字节顺序字节数和对齐方式
@nativenative 凑够4个字节
=nativestandard 按原字节数
<little-endianstandard 按原字节数
>big-endianstandard 按原字节数
!network (= big-endian)standard 按原字节数

例子

import struct  
  
# 定义数据  
a = b"hello"  
b = b"world!"  
c = 20  
d = 42.56  
  
# 打包  
binStr = struct.pack("5s6sif", a, b, c, d)  
print (len(binStr))
binStr2 = struct.pack("i", c)  
  
# 解包  
e, f, g, h = struct.unpack("5s6sif", binStr)  
print (e, f, g, h )
  
# 注意unpack返回的是tuple,如果不按规定格式书写,则返回值将改变类型  
i, = struct.unpack("i", binStr2)  
print (i)
i = struct.unpack("i", binStr2)  
print (i)
  
# 计算转换字节长度  
print (struct.calcsize("5s6sif"))