问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

python3 利用struct.pack 动态组建字节流

发布网友 发布时间:2022-04-18 08:38

我来回答

3个回答

懂视网 时间:2022-04-18 13:00

最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,这篇文章就主要介绍了Python中struct模块对字节流/二进制流的操作,需要的朋友可以参考借鉴。

前言

最近使用Python解析IDX文件格式的MNIST数据集,需要对二进制文件进行读取操作,其中我使用的是struct模块。查了网上挺多教程都写的挺好的,不过对新手不是很友好,所以我重新整理了一些笔记以供快速上手。

注:教程中以下四个名词同义:二进制流、二进制数组、字节流、字节数组

快速上手

在struct模块中,将一个整型数字、浮点型数字或字符流(字符数组)转换为字节流(字节数组)时,需要使用格式化字符串fmt告诉struct模块被转换的对象是什么类型,比如整型数字是'i',浮点型数字是'f',一个ascii码字符是's'。

def demo1():
 # 使用bin_buf = struct.pack(fmt, buf)将buf为二进制数组bin_buf
 # 使用buf = struct.unpack(fmt, bin_buf)将bin_buf二进制数组反转换回buf

 # 整型数 -> 二进制流
 buf1 = 256
 bin_buf1 = struct.pack('i', buf1) # 'i'代表'integer'
 ret1 = struct.unpack('i', bin_buf1)
 print bin_buf1, ' <====> ', ret1

 # 浮点数 -> 二进制流
 buf2 = 3.1415
 bin_buf2 = struct.pack('d', buf2) # 'd'代表'double'
 ret2 = struct.unpack('d', bin_buf2)
 print bin_buf2, ' <====> ', ret2

 # 字符串 -> 二进制流
 buf3 = 'Hello World'
 bin_buf3 = struct.pack('11s', buf3) # '11s'代表长度为11的'string'字符数组
 ret3 = struct.unpack('11s', bin_buf3)
 print bin_buf3, ' <====> ', ret3

 # 结构体 -> 二进制流
 # 假设有一个结构体
 # struct header {
 # int buf1;
 # double buf2;
 # char buf3[11];
 # }
 bin_buf_all = struct.pack('id11s', buf1, buf2, buf3)
 ret_all = struct.unpack('id11s', bin_buf_all)
 print bin_buf_all, ' <====> ', ret_all

输出结果如下:

Python中struct模块对字节流/二进制流的操作教程
demo1输出结果

详解struct模块

主要函数

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

# 按照给定的格式化字符串,把数据封装成字符串(实际上是类似于c结构体的字节流)
string = struct.pack(fmt, v1, v2, ...)

# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
tuple = unpack(fmt, string)

# 计算给定的格式(fmt)占用多少字节的内存
offset = calcsize(fmt)

struct中的格式化字符串

struct中支持的格式如下表:


FormatC TypePython字节数
xpad byteno value1
ccharstring of length 11
bsigned charinteger1
Bunsigned charinteger1
?_Boolbool1
hshortinteger2
Hunsigned shortinteger2
iintinteger4
Iunsigned intinteger or lon4
llonginteger4
Lunsigned longlong4
qlong longlong8
Qunsigned long longlong8
ffloatfloat4
ddoublefloat8
schar[]string1
pchar[]string1
Pvoid *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
@nativenative 凑够4个字节
=nativestandard 按原字节数
<little-endianstandard 按原字节数
>big-endianstandard 按原字节数
!network (= big-endian)standard 按原字节数

使用方法是放在fmt的第一个位置,就像'@5s6sif'

更多Python中struct模块对字节流/二进制流的操作教程相关文章请关注PHP中文网!

热心网友 时间:2022-04-18 10:08

a = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
fmt = str(len(a)) + 'H' # 默认小端模式
struct.pack(fmt, *a) # 列表a前面加*,表示将a解压后单个传入参数
推理:a如果是动态变化的list,或者动态截取a其中一段来转换成字节流都是可以的

热心网友 时间:2022-04-18 11:26

序列化写数据流时,应该用python的IO工具。struck.pack只作为单个数据的序列化过程。
比如文件

file=open(......
file.write(struck.pack(..........));
file.write(struck.pack(..........));
或者内存
f = io.BytesIO()
f.write(struck.pack(..........))
f.write(struck.pack(..........))
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
华为freebuds4i切歌怎么操作_华为freebuds4i怎么切歌 华为freebuds pro切歌方法_华为freebuds pro怎么切歌 华为耳机怎么切换下一曲 欧美电影,好像是宠物有一个世界,宠物会想办法跟主人的灵魂互换占据 ...的名字,欧洲中世纪,一个王子的继母把他的灵魂和狗的灵魂互换了... 问一部外国电影的名字 剧情记得不大清楚l了 是前几年的片子 灵魂互换的... HUAWEI 华为 AGS2-W09 10.1英寸平板电脑 (香槟金、64GB+4GB、WiFi版... 诛仙3百法和千法差距大吗 微信怎么解除应用授权登录 授权应用删除方法 微信怎么解除应用授权登录授权应用删除方法 笔记本电脑登陆后,桌面黑屏,但我的电脑仍然能打开,求助 笔记本电脑正常黑屏后如何打开 凤凰传奇《我和草原有个约定》MV是在哪里拍的啊 好美啊 我想去玩 谁有凤凰传奇 - 我和草原有个约会歌曲百度云网盘资源下载 求凤凰传奇 - 我和草原有个约定(交响乐版)音乐免费百度云网盘资源 (我和草原有个约定)-降央卓玛 这首歌词:? 有谁知道文玩核桃有几个种,怎样分辨,求答! 请帮忙起个英文名!!! 红心核桃小孩吃有什么好处 请帮我取个好的英文名 印度女子名Chahna的读音? 车辆违章罚款在哪家银行可以办理 英雄联盟韩服,为什么我更新这么慢 LOL为什么更新很慢 每次更新完到在安装的时候就不动了 LOL为什么每次更新这么慢 qq被举报能解除吗 QQ举报一定成功吗? 举报了能撤销吗??? 我举报了一个人的QQ,能撤销吗 qq举报可以撤去吗? 我投诉了一个qq 号,想撤诉可以么? 什么样的马桶不容易堵 什么样子的马桶不容易堵啊,求推荐 有移位过马桶的朋友吗,参考一下买什么样的马桶不堵塞 闲鱼互刷互赞被封号还能解开吗 在python中如何从二进制文件中读取信息? 全民当家真的是炸骗团伙吗? 抖音普通号可以发布反诈骗内容吗? 全民当家是不是骗子? 全民帮手软件是诈骗吗 下载全民反诈诈骗了钱全民反诈会被我的钱冻结了吗 看到一个新闻说有个全民防诈骗月的活动,上面说腾讯手机管家能举报电话诈骗,有用过的吗?怎样啊? 内蒙古建筑行业12j6里连廊的高度要求 室外连廊门洞最少多高 为什么说中户不可能南北通透? 我是学建筑的,想请高手帮忙住宅的连廊设计规范是什么? 电梯之间的通道只有一条高空消防连廊正常吗? 请教:入户连廊,连廊的安全性高吗?怀疑? 飞利浦电动牙刷HX9354套装为什么没有适配器 红米3s怎么截长图. 红米3S按电源键和音量键不能截屏,怎么弄