操作字节列表时使用pack_into()的替代方案?

2 投票
2 回答
1277 浏览
提问于 2025-04-15 12:55

我正在把一个二进制文件读入到一个列表中,并解析这些二进制数据。我使用unpack()来提取数据中的某些部分,转换成基本的数据类型。接下来,我想修改这些数据,然后再把它们放回原来的字节列表中。使用pack_into()会很简单,但我现在用的是Python 2.4,而pack_into()是在2.5版本才引入的。

有没有人知道有什么好的方法可以实现类似pack_into()的功能,把数据序列化成我想要的样子?

2 个回答

1

你是说要在一个缓冲区对象里编辑数据吗?关于如何直接在Python中操作这些东西的文档其实不多。

如果你只是想在字符串里编辑字节,那其实很简单;从Python 2.5开始有了struct.pack_into这个功能,但struct.pack这个功能早就有了:

import struct
s = open("file").read()
ofs = 1024
fmt = "Ih"
size = struct.calcsize(fmt)

before, data, after = s[0:ofs], s[ofs:ofs+size], s[ofs+size:]
values = list(struct.unpack(fmt, data))
values[0] += 5
values[1] /= 2
data = struct.pack(fmt, *values)
s = "".join([before, data, after])
4

你有没有看过bitstring这个模块?它的设计目的是让你处理二进制数据时,比直接使用structarray模块要简单很多。

这个模块特别适合在比特级别上工作,但处理字节也没问题。而且它还支持Python 2.4。

from bitstring import BitString
s = BitString(filename='somefile')

# replace byte range with new values
# The step of '8' signifies byte rather than bit indicies.
s[10:15:8] = '0x001122'

# Search and replace byte value with two bytes
s.replace('0xcc', '0xddee', bytealigned=True)

# Different interpretations of the data are available through properties
if s[5:7:8].int > 1000:
    s[5:7:8] = 1000

# Use the bytes property to get back to a Python string
open('newfile', 'wb').write(s.bytes)

BitString中存储的数据其实就是一个array对象,不过它提供了一整套功能和特殊方法,让你修改和理解这些数据变得简单。

撰写回答