Python中struct模块对字节流/二进制流的操作教程


Posted in Python onJanuary 21, 2017

前言

最近使用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中支持的格式如下表:

Format C Type Python 字节数
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 lon 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根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:

Character Byte order Size and alignment
@ native native 凑够4个字节
= native standard 按原字节数
little-endian standard 按原字节数
> big-endian standard 按原字节数
! network (= big-endian) standard 按原字节数

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助如果有疑问大家可以留言交流。

Python 相关文章推荐
Python 检查数组元素是否存在类似PHP isset()方法
Oct 14 Python
centos 下面安装python2.7 +pip +mysqld
Nov 18 Python
Python简单的制作图片验证码实例
May 31 Python
详解Python map函数及Python map()函数的用法
Nov 16 Python
对python中执行DOS命令的3种方法总结
May 12 Python
python 读取文本文件的行数据,文件.splitlines()的方法
Jul 12 Python
使用pandas 将DataFrame转化成dict
Dec 10 Python
Python count函数使用方法实例解析
Mar 23 Python
python 如何用urllib与服务端交互(发送和接收数据)
Mar 04 Python
python Polars库的使用简介
Apr 21 Python
python unittest单元测试的步骤分析
Aug 02 Python
使用Python开发冰球小游戏
Apr 30 Python
python使用xlrd与xlwt对excel的读写和格式设定
Jan 21 #Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
Jan 21 #Python
python实现的多线程端口扫描功能示例
Jan 21 #Python
Python 字符串大小写转换的简单实例
Jan 21 #Python
linux平台使用Python制作BT种子并获取BT种子信息的方法
Jan 20 #Python
python dict 字典 以及 赋值 引用的一些实例(详解)
Jan 20 #Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
Jan 20 #Python
You might like
PHP中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
php通过baihui网API实现读取word文档并展示
2015/06/22 PHP
PHP输出多个元素的排列或组合的方法
2017/03/14 PHP
javascript获得CheckBoxList选中的数量
2009/10/27 Javascript
javascript JSON操作入门实例
2010/04/16 Javascript
jQuery 学习第七课 扩展jQuery的功能 插件开发
2010/05/17 Javascript
使用jquery的ajax需要注意的地方dataType的设置
2013/08/12 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
调用HttpHanlder的几种返回方式小结
2013/12/20 Javascript
图片翻转效果具体实现代码
2014/01/09 Javascript
JS获取单击按钮单元格所在行的信息
2014/06/17 Javascript
JavaScript删除指定子元素代码实例
2015/01/13 Javascript
JavaScript中的this关键字使用方法总结
2015/03/13 Javascript
跟我学习javascript的作用域与作用域链
2015/11/19 Javascript
AngularJS控制器之间的通信方式详解
2016/11/03 Javascript
js如何实现元素曝光上报
2019/08/07 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
numpy.random.seed()的使用实例解析
2018/02/03 Python
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
python二维列表一维列表的互相转换实例
2018/07/02 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
2020/05/11 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
班级入场式解说词
2014/02/01 职场文书
旅游管理毕业生自荐书
2014/02/02 职场文书
会计的岗位职责
2014/03/15 职场文书
《菜园里》教学反思
2014/04/17 职场文书
超市开业庆典策划方案
2014/05/14 职场文书
政协调研汇报材料
2014/08/15 职场文书
2014年会计主管工作总结
2014/12/20 职场文书
计算机考试作弊检讨书1000字
2015/01/01 职场文书
教师年度考核自我评鉴
2015/08/11 职场文书
2019年鼓励无偿献血倡议书
2019/09/17 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP