📅  最后修改于: 2023-12-03 14:46:38.990000             🧑  作者: Mango
在Python中,有一个非常实用的模块叫作struct
,它能够让我们方便地处理二进制数据。如果你需要读取或者生成二进制数据,那么就可以用到该模块。在这里我们将为大家介绍一下该模块的基本使用和一些常见应用。
使用struct
模块需要先导入包:
import struct
对于一个二进制数据,我们需要先定义它的格式,然后再进行处理。下面是一些常用的格式:
| 字符 | 对应数据类型 |
| ---- | ----------- |
| b
| 带符号字节 |
| B
| 无符号字节 |
| h
| 带符号短整数 |
| H
| 无符号短整数 |
| i
| 带符号整数 |
| I
| 无符号整数 |
| q
| 带符号长整数 |
| Q
| 无符号长整数 |
| f
| 单精度浮点数 |
| d
| 双精度浮点数 |
接下来,我们需要使用pack
函数来将数据按格式打包成二进制数据:
data = struct.pack('i', 10)
这个函数的第一个参数是格式字符串,意思是对应的数据类型。第二个参数是对应的数据。上面的代码将整数10
按照i
格式打包成了二进制流。
我们也可以使用unpack
函数将一个已经打包的二进制流解包成对应的数据:
num = struct.unpack('i', data)[0]
该函数的第一个参数同样是格式字符串,第二个参数则是需要解包的二进制流,函数会返回一个元组,我们可以通过下标来获取对应的值,比如上面的例子中就是第一个元素。
在网络通信中,经常需要处理各种类型的数据流。使用struct
模块可以方便地将数据打包成网络字节序(network byte order),也可以将网络字节序的数据解包成本机字节序(host byte order),进而进行操作。
import socket
import struct
def pack_short(short):
# 打包短整数(2字节)成网络字节序
return struct.pack('!H', short)
def unpack_short(short_bytes):
# 将网络字节序的短整数解包成本机字节序
return struct.unpack('!H', short_bytes)[0]
def send_short(sock, short):
# 发送短整数给socket
sock.send(pack_short(short))
def recv_short(sock):
# 接收socket中的短整数
short_bytes = sock.recv(2)
return unpack_short(short_bytes)
上面是一个处理短整数的例子,包含了打包成网络字节序、解包成本机字节序、发送给socket和从socket接收等操作。
对于一些二进制格式的文件(如图片、视频等),使用struct
模块可以对它们进行解析和读取,进而获取其中的数据。下面是一个读取BMP图片文件中像素数据的例子。
BMP图片格式是简单的二进制格式,由一个位图文件头和一个位图信息头组成,我们可以根据这些信息来读取图片像素数据。
import struct
with open('image.bmp', 'rb') as f:
# 读取位图文件头
bmp_header = f.read(14)
if bmp_header[0:2] != b'BM':
raise Exception('Not a BMP file')
# 读取位图信息头
bmp_info_header = f.read(40)
width, height, _, _, _, _, _, _, _, _ = struct.unpack('<iiiiiiiiii', bmp_info_header)
# 检查是否为24位真彩色图像
if struct.unpack('<h', bmp_info_header[14:16])[0] != 24:
raise Exception('Not a 24-bit true-color BMP file')
# 读取像素数据
f.seek(struct.unpack('<i', bmp_header[10:14])[0])
pixel_data = f.read(width * height * 3)
上面的代码中,我们根据BMP文件格式中的位图文件头和位图信息头来读取文件信息和像素数据,并进行一些基本的检查。由于BMP是小端字节序(little-endian)的格式,因此需要使用<
进行对应的解析。
struct
模块是Python中非常实用的一个库,它可以帮助我们方便地处理二进制数据。如果你需要进行二进制数据的读取、生成或者传输等操作,那么就一定要使用这个模块。