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实现的字典值比较功能示例
Jan 08 Python
python导入坐标点的具体操作
May 10 Python
通过pycharm使用git的步骤(图文详解)
Jun 13 Python
详解DeBug Python神级工具PySnooper
Jul 03 Python
使用python对多个txt文件中的数据进行筛选的方法
Jul 10 Python
python中@property和property函数常见使用方法示例
Oct 21 Python
Python 使用 prettytable 库打印表格美化输出功能
Dec 26 Python
pytorch 中pad函数toch.nn.functional.pad()的用法
Jan 08 Python
Python tkinter和exe打包的方法
Feb 05 Python
基于python模拟bfs和dfs代码实例
Nov 19 Python
selenium自动化测试入门实战
Dec 21 Python
通过Python把学姐照片做成拼图游戏
Feb 15 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中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
setcookie中Cannot modify header information-headers already sent by错误的解决方法详解
2013/05/08 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
浅谈php扩展imagick
2014/06/02 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
基于dom编程中 动态创建与删除元素的使用
2013/04/17 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
基于Node.js的JavaScript项目构建工具gulp的使用教程
2016/05/20 Javascript
WebSocket+node.js创建即时通信的Web聊天服务器
2016/08/08 Javascript
Vue.js动态组件解析
2016/09/09 Javascript
Bootstrap popover用法详解
2016/12/22 Javascript
node.js平台下利用cookie实现记住密码登陆(Express+Ejs+Mysql)
2017/04/26 Javascript
详解动画插件wow.js的使用方法
2017/09/13 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
2017/10/16 Javascript
JavaScript基础心法 数据类型
2018/03/05 Javascript
vue微信分享的实现(在当前页面分享其他页面)
2019/04/16 Javascript
一篇文章,教你学会Vue CLI 插件开发
2019/04/17 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
2019/09/27 Javascript
vue 扩展现有组件的操作
2020/08/14 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
Python 字典(Dictionary)操作详解
2014/03/11 Python
Python通过select实现异步IO的方法
2015/06/04 Python
Python给你的头像加上圣诞帽
2018/01/04 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
keras 指定程序在某块卡上训练实例
2020/06/22 Python
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
婴儿鞋,独特的婴儿服装和配件:Zutano
2018/11/03 全球购物
终端业务员岗位职责
2013/11/27 职场文书
我的五年职业生涯规划
2014/01/23 职场文书
机械设计专业大学生职业生涯规划书范文
2014/09/13 职场文书
安全保证书格式
2015/02/28 职场文书
mysql 数据插入优化方法之concurrent_insert
2021/07/01 MySQL
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers
Win11 vmware不兼容怎么办?Win11与VMware虚拟机不兼容的解决方法
2023/01/09 数码科技