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

在python中如何从二进制文件中读取信息?

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

我来回答

2个回答

懂视网 时间: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

你是指读入二进制文件吧?
可以使用numpy.fromfile(),也可以使用open(filename, 'rb'),其中的'b'就是二进制的意思,然后使用文件类型的read方法,读取一些字节,再用struct.unpack()方法来解析二进制。
第一种方法是一次性读入文件(或文件的前多少个连续字节)到一个数组中,因此,灵活性差。
第二种方法灵活性很高,可以读取任意位置(使用文件的seek()方法跳跃位置)的二进制数据,再使用struct.unpack()方法来进行各种二进制解析。

提示:二进制文件是不保留存储方式的数据格式,因此,读二进制文件时应该知道二进制文件的存储格式。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
我用耳机玩爱唱久久怎么唱出来的不响? 电脑ktv点歌软件有哪些电脑用什么点歌软件比较好 更换变速箱油后,汽车刹车和起步时底盘常有嘎啦嘎啦的异响是什么原因... 格兰仕空调口碑怎么样 格兰仕空调的优缺点有哪些? 格兰仕空调怎么样?质量好吗? 什么是PNC金融服务集团 挖出蛇是好事还是坏事? 微信换行怎么换到下一行 微信如何将自己的位置定位发绐别人 闲鱼互刷互赞被封号还能解开吗 有移位过马桶的朋友吗,参考一下买什么样的马桶不堵塞 什么样子的马桶不容易堵啊,求推荐 什么样的马桶不容易堵 python3 利用struct.pack 动态组建字节流 笔记本电脑登陆后,桌面黑屏,但我的电脑仍然能打开,求助 笔记本电脑正常黑屏后如何打开 凤凰传奇《我和草原有个约定》MV是在哪里拍的啊 好美啊 我想去玩 谁有凤凰传奇 - 我和草原有个约会歌曲百度云网盘资源下载 求凤凰传奇 - 我和草原有个约定(交响乐版)音乐免费百度云网盘资源 (我和草原有个约定)-降央卓玛 这首歌词:? 有谁知道文玩核桃有几个种,怎样分辨,求答! 请帮忙起个英文名!!! 红心核桃小孩吃有什么好处 请帮我取个好的英文名 印度女子名Chahna的读音? 车辆违章罚款在哪家银行可以办理 英雄联盟韩服,为什么我更新这么慢 LOL为什么更新很慢 每次更新完到在安装的时候就不动了 LOL为什么每次更新这么慢 全民当家真的是炸骗团伙吗? 抖音普通号可以发布反诈骗内容吗? 全民当家是不是骗子? 全民帮手软件是诈骗吗 下载全民反诈诈骗了钱全民反诈会被我的钱冻结了吗 看到一个新闻说有个全民防诈骗月的活动,上面说腾讯手机管家能举报电话诈骗,有用过的吗?怎样啊? 内蒙古建筑行业12j6里连廊的高度要求 室外连廊门洞最少多高 为什么说中户不可能南北通透? 我是学建筑的,想请高手帮忙住宅的连廊设计规范是什么? 电梯之间的通道只有一条高空消防连廊正常吗? 请教:入户连廊,连廊的安全性高吗?怀疑? 飞利浦电动牙刷HX9354套装为什么没有适配器 红米3s怎么截长图. 红米3S按电源键和音量键不能截屏,怎么弄 萤石云远程监控探头能与一般的无线路由器相匹配吗 使用萤石,必须有路由器吗。无线网络能安装萤石吗 为什么我的wampserver切换成在线会报错 我想切换成在线状态 我用的是SQL 看了下好像能用 有没有在线sql server练习环境 sql 查询 所有用户的在线时间