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转换摩斯密码示例
Feb 16 Python
Python写的PHPMyAdmin暴力破解工具代码
Aug 06 Python
Python正则表达式匹配中文用法示例
Jan 17 Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 Python
Python打印输出数组中全部元素
Mar 13 Python
Python实现随机生成手机号及正则验证手机号的方法
Apr 25 Python
对Python中DataFrame选择某列值为XX的行实例详解
Jan 29 Python
Python正则表达式实现简易计算器功能示例
May 07 Python
在cmd中查看python的安装路径方法
Jul 03 Python
Python3视频转字符动画的实例代码
Aug 29 Python
Python包,__init__.py功能与用法分析
Jan 07 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 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
杏林同学录(七)
2006/10/09 PHP
根据ip调用新浪api获取城市名并转成拼音
2014/03/07 PHP
php对文件进行hash运算的方法
2015/04/03 PHP
smarty高级特性之对象的使用方法
2015/12/25 PHP
PHP下载远程图片并保存到本地方法总结
2016/01/22 PHP
CI分页类首页、尾页不显示的解决方法
2016/03/28 PHP
PHP将URL转换成短网址的算法分享
2016/09/13 PHP
解决Laravel5.2 Auth认证退出失效的问题
2019/10/14 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
jQuery Ajax 全解析
2009/02/08 Javascript
JavaScript 学习小结(适合新手参考)
2009/07/30 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
jQuery悬停文字提示框插件jquery.tooltipster.js用法示例【附demo源码下载】
2016/07/19 Javascript
vue.js移动端app实战1:初始配置详解
2017/07/24 Javascript
vue中的provide/inject的学习使用
2018/05/09 Javascript
javascript实现页面的实时时钟显示示例
2020/08/06 Javascript
vue 实现图片懒加载功能
2020/12/31 Vue.js
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
2013/01/17 Python
Python中__init__和__new__的区别详解
2014/07/09 Python
简单介绍Python中的struct模块
2015/04/28 Python
正确理解Python中if __name__ == '__main__'
2019/01/24 Python
Python自动化完成tb喵币任务的操作方法
2019/10/30 Python
使用Python将Exception异常错误堆栈信息写入日志文件
2020/04/08 Python
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
法国足球商店:Footcenter
2019/07/06 全球购物
屈臣氏菲律宾官网:Watsons菲律宾
2020/06/30 全球购物
explicit和implicit的含义
2012/11/15 面试题
什么是测试驱动开发(TDD)
2012/02/15 面试题
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
产品推广策划方案
2014/05/10 职场文书
写作之关于描写老人的好段摘抄
2019/11/14 职场文书
python中如何对多变量连续赋值
2021/06/03 Python
python处理json数据文件
2022/04/11 Python
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL
MySQL中EXPLAIN语句及用法
2022/05/20 MySQL