Python使用struct处理二进制(pack和unpack用法)

有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体.

struct模块中最重要的三个函数是pack(), unpack(), calcsize()

# 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
pack(fmt, v1, v2, ...) 

# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
unpack(fmt, string)  

# 计算给定的格式(fmt)占用多少字节的内存
calcsize(fmt)

上述fmt中,支持的格式为:

FORMAT C TYPE PYTHON TYPE STANDARD SIZE NOTES
x pad byte no value - -
c char string of length 1 1 -
b signed char integer 1 (3)
B unsigned char integer 1 (3)
? _Bool bool 1 (1)
h short integer 2 (3)
H unsigned short integer 2 (3)
i int integer 4 (3)
I unsigned int integer 4 (3)
l long integer 4 (3) -
L unsigned long integer 4 (3)
q long long integer 8 (2), (3)
Q unsigned long long integer 8 (2), (3)
f float float 4 (4)
d double float 8 (4)
s char[] string - -
p char[] string - -
P void * integer - (5), (3)

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

例子1:

结构体如下:

struct Header
{
 unsigned short id;
 char[4] tag;
 unsigned int version;
 unsigned int count;
}

通过socket.recv接收到了一个上面的结构体数据,存在字符串s中,现在需要把它解析出来,可以使用unpack()函数:

import struct
id, tag, version, count = struct.unpack("!H4s2I", s)

上面的格式字符串中,!表示我们要使用网络字节顺序解析,因为我们的数据是从网络中接收到的,在网络上传送的时候它是网络字节顺序的.后面的H表示 一个unsigned short的id,4s表示4字节长的字符串,2I表示有两个unsigned int类型的数据.

就通过一个unpack,现在id, tag, version, count里已经保存好我们的信息了.

同样,也可以很方便的把本地数据再pack成struct格式:

ss = struct.pack("!H4s2I", id, tag, version, count);

pack函数就把id, tag, version, count按照指定的格式转换成了结构体Header,ss现在是一个字符串(实际上是类似于c结构体的字节流),可以通过 socket.send(ss)把这个字符串发送出去。

例子2:

import struct

a=12.34

# 将a变为二进制
bytes=struct.pack('i',a)

此时bytes就是一个string字符串,字符串按字节同a的二进制存储内容相同。

再进行反操作,现有二进制数据bytes,(其实就是字符串),将它反过来转换成python的数据类型:

# 注意,unpack返回的是tuple !!
a,=struct.unpack('i',bytes)

如果是由多个数据构成的,可以这样:

a='hello'
b='world!'
c=2
d=45.123

bytes=struct.pack('5s6sif',a,b,c,d)
此时的bytes就是二进制形式的数据了,可以直接写入文件比如 binfile.write(bytes)

然后,当我们需要时可以再读出来,bytes=binfile.read()

再通过struct.unpack()解码成python变量:

a,b,c,d=struct.unpack('5s6sif',bytes)

'5s6sif'这个叫做fmt,就是格式化字符串,由数字加字符构成,5s表示占5个字符的字符串,2i,表示2个整数等等,下面是可用的字符及类型,ctype表示可以与python中的类型一一对应。

注意:二进制文件处理时会碰到的问题

我们使用处理二进制文件时,需要用如下方法:

binfile=open(filepath,'rb')  #读二进制文件

binfile=open(filepath,'wb') #写二进制文件

那么和binfile=open(filepath,'r')的结果到底有何不同呢?

不同之处有两个地方:

第一,使用'r'的时候如果碰到'0x1A',就会视为文件结束,这就是EOF。使用'rb'则不存在这个问题。即,如果你用二进制写入再用文本读出的话,如果其中存在'0X1A',就只会读出文件的一部分。使用'rb'的时候会一直读到文件末尾。

第二,对于字符串x='abc\ndef',我们可用len(x)得到它的长度为7,\n我们称之为换行符,实际上是'0X0A'。当我们用'w'即文本方式写的时候,在windows平台上会自动将'0X0A'变成两个字符'0X0D','0X0A',即文件长度实际上变成8.。当用'r'文本方式读取时,又自动的转换成原来的换行符。如果换成'wb'二进制方式来写的话,则会保持一个字符不变,读取时也是原样读取。所以如果用文本方式写入,用二进制方式读取的话,就要考虑这多出的一个字节了。'0X0D'又称回车符。linux下不会变。因为linux只使用'0X0A'来表示换行。

以上就是Python使用struct处理二进制(pack和unpack用法)的详细内容,更多关于python struct处理二进制的资料请关注我们其它相关文章!

(0)

相关推荐

  • python pip如何手动安装二进制包

    python中使用pip安装扩展包的时候,有时候会遇到如下类似报错: Running setup.py install for mysqlclient ... error ...(中间报错信息省略) building 'MySQLdb._mysql' extension error: Microsoft Visual C++ 14.0 is required. Get it with "Build Tools for Visual Studio": https://visualstud

  • Python如何向SQLServer存储二进制图片

    需求是需要用python往 SqlServer中的image类型字段中插入二进制图片 核心代码,研究好几个小时的代码: 安装pywin32,adodbapi image_url = "图片链接" try: image_result = session.get(url=image_url, headers=headers, stream=True) except: image_result = session.get(url=image_url, headers=headers, str

  • python十进制转二进制的详解

    python十进制转二进制 python中十进制转二进制使用 bin() 函数. bin() 返回一个整数 int 或者长整数 long int 的二进制表示. 下面是使用示例: >>>bin(10) '0b1010' >>> bin(20) '0b10100' 补充:十进制转8进制和16进制的方法: # -*- coding: UTF-8 -*- # 获取用户输入十进制数 dec = int(input("输入数字:")) print("

  • python 读取二进制 显示图片案例

    我就废话不多说了,大家还是直接看代码吧! import matplotlib.pyplot as plt import numpy as np f = open('bwall.bmpx', mode='rb') x = np.fromfile(f, dtype=np.ubyte) #x = x[0:1920] x = x[1920:3840] #x = x[3840:5760] x = x.reshape(60,32) #print((x)) plt.imshow(x) plt.axis('of

  • Python二进制文件读取并转换为浮点数详解

    本文所用环境: Python 3.6.5 |Anaconda custom (64-bit)| 引言 由于某些原因,需要用python读取二进制文件,这里主要用到struct包,而这个包里面的方法主要是unpack.pack.calcsize.详细介绍可以看:Python Struct 官方文档.这里主要讨论,python二进制转浮点数的操作. python中一个float类型的数占4个字节. 二进制数据转float,可以用struct.unpack()来实现. 小文件读取 较小的文件,可以一次

  • Python读取二进制文件代码方法解析

    问题 有二进制文件中保存了 20 亿个 2 Bytes 的数,需将其读出,每 20000 个数作图,拟合后输出结果. 解决 # -*- coding: utf-8 -*- """ @author: kurrrr """ import struct def main(): data_file = open('run0035.bin', 'rb') data_temp = data_file.read(2) data_short, = struct.

  • Python+OpenCV实现将图像转换为二进制格式

    在学习tensorflow的过程中,有一个问题,tensorflow在训练的过程中读取的是二进制图像数据库文件,而不是图像文件,因此 在进行训练.测试之前需要将图像文件转换为二进制格式. 下面是我在ubuntu中使用python+OpenCV读取图像并转换为二进制格式文件的代码. #coding=utf-8 ''' Created on 2016年3月24日 使用Opencv读取图像将其保存为二进制格式文件,再读取该二进制文件,转换为图像进行显示 @author: hanchao ''' imp

  • Python的bit_length函数来二进制的位数方法

    自Python3.1中,整数bit_length方法允许查询二进制的位数或长度. 常规做法: >>> bin(256) '0b100000000' >>> len(bin(256)) - 2 9 >>> 使用函数: >>> bin(256), (256).bit_length() ('0b100000000', 9) >>> X = 99 >>> bin(X), X.bit_length() ('0

  • 将python图片转为二进制文本的实例

    写在最前面: 我在研究机器学习的过程中,给的数据集是手写数字图片被处理后的由0,1表达的txt文件,今天写一写关于图片转化为二进制txt文件的python实践 在这里,我们使用python中的Pillow库,Pillow库中有一个很重要的类是Image,可以对图片进行很多处理. 首先,导入Image类 from PIL import Image 打开图片 im=Image.open('1.jpg') 获取图片宽和高 width=im.size[0] height=im.size[1] 也可以这样

  • Python如何读写二进制数组数据

    问题 你想读写一个二进制数组的结构化数据到Python元组中. 解决方案 可以使用 struct 模块处理二进制数据. 下面是一段示例代码将一个Python元组列表写入一个二进制文件,并使用 struct 将每个元组编码为一个结构体. from struct import Struct def write_records(records, format, f): ''' Write a sequence of tuples to a binary file of structures. '''

  • 关于Python字符编码与二进制不得不说的一些事

    二进制 核心思想: 冯诺依曼 + 图灵机 电如何表示状态,才能稳定? 计算机开始设计的时候并不是考虑简单,而是考虑能自动完成任务与结果的可靠性, 简单始终是建立再稳定.可靠基础上 经过尝试10进制,但很难检查电流的状态差异并且很难稳定状态,最稳定的检查是 通电和不通电状态,共两种状态那就规定 通电为 1 不通电 为 0,1和0的状态逻 辑被称为比特 Bit 那么如何用 0 和 1 表示数字和字符呢? 首先找出需要表示的字符,英文字符和数字字符才100多个,需要 7 个二进制位就 可以全部表示,但

  • Python读入mnist二进制图像文件并显示实例

    图像文件是自己仿照mnist格式制作,每张图像大小为128*128 import struct import matplotlib.pyplot as plt import numpy as np #读入整个训练数据集图像 filename = 'train-images-idx3-ubyte' binfile = open(filename, 'rb') buf = binfile.read() #读取头四个32bit的interger index = 0 magic, numImages,

随机推荐