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实现dict版图遍历示例
Feb 19 Python
python使用正则表达式分析网页中的图片并进行替换的方法
Mar 26 Python
pandas通过索引进行排序的示例
Nov 16 Python
python实现汽车管理系统
Nov 30 Python
Python设计模式之简单工厂模式实例详解
Jan 22 Python
python绘制漏斗图步骤详解
Mar 04 Python
python 实现批量替换文本中的某部分内容
Dec 13 Python
Python下划线5种含义代码实例解析
Jul 10 Python
Pycharm的Available Packages为空的解决方法
Sep 18 Python
如何基于python实现年会抽奖工具
Oct 20 Python
python pillow库的基础使用教程
Jan 13 Python
OpenCV项目实践之停车场车位实时检测
Apr 11 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+mysql)
2007/11/23 PHP
php单链表实现代码分享
2016/07/04 PHP
PHP中快速生成随机密码的几种方式
2017/04/17 PHP
JavaScript脚本语言在网页中的简单应用
2007/05/13 Javascript
gridpanel动态加载数据的实例代码
2013/07/18 Javascript
浅析Node在构建超媒体API中的作用
2014/07/30 Javascript
jquery处理页面弹出层查询数据等待操作实例
2015/03/25 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
基于jQuery的Web上传插件Uploadify使用示例
2016/05/19 Javascript
基于javascript的异步编程实例详解
2017/04/10 Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
2017/05/03 Javascript
Vue.2.0.5实现Class 与 Style 绑定的实例
2017/06/20 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
jQuery dateRangePicker插件使用方法详解
2017/07/28 jQuery
vue中实现methods一个方法调用另外一个方法
2018/02/08 Javascript
详解使用jQuery.i18n.properties实现js国际化
2018/05/04 jQuery
JavaScript多态与封装实例分析
2018/07/27 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
vue实现树状表格效果
2020/12/29 Vue.js
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
Python升级提示Tkinter模块找不到的解决方法
2014/08/22 Python
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
python同时给两个收件人发送邮件的方法
2015/04/30 Python
Python的Twisted框架上手前所必须了解的异步编程思想
2016/05/25 Python
Python实现的排列组合计算操作示例
2017/10/13 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
Python关于拓扑排序知识点讲解
2021/01/04 Python
HTML5 Canvas实现玫瑰曲线和心形图案的代码实例
2014/04/10 HTML / CSS
德购商城:德国进口直邮商城
2017/06/13 全球购物
李宁官方网店:中国运动品牌
2017/11/02 全球购物
英国女性时尚品牌:Apricot
2018/12/04 全球购物
学历公证委托书
2014/04/09 职场文书
医院院务公开实施方案
2014/05/03 职场文书
MySQL 存储过程的优缺点分析
2021/05/20 MySQL
MySQL中CURRENT_TIMESTAMP的使用方式
2021/11/27 MySQL
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers