gpt4 book ai didi

Python:从二进制数据中解压结构数组的最佳方法是什么

转载 作者:行者123 更新时间:2023-12-05 06:15:58 25 4
gpt4 key购买 nike

我正在解析二进制文件格式(OpenType 字体文件)。该格式是许多不同结构类型的复杂树,但一个重复出现的模式是具有特定格式的记录数组。我使用 struct.unpack 编写了代码,一次获取一条记录。但我想知道是否缺少一种方法来解析整个记录数组?

以下是一种特定记录数组的解压缩结果示例:

[{'glyphID': 288, 'paletteIndex': 0}, {'glyphID': 289, 'paletteIndex': 1}, {'glyphID': 518, 'paletteIndex': 0}, ...]    list

这就是我目前正在做的事情:我创建了一个通用函数来解压缩任意记录数组(在任何给定调用中的记录格式一致)。

def tryReadRecordsArrayFromBuffer(buffer, numRecords, format, fieldNames):
recordLength = struct.calcsize(format)
array = []
index = 0
for i in range(numRecords):
record = {}
vals = struct.unpack(format, buffer[index : index + recordLength])
for k, v in zip(fieldNames, vals):
record[k] = v
array.append(record)
index += recordLength

return array

buffer 参数是一个字节序列,其大小至少为数组的大小,第一个要解包的记录位于序列的开头。

根据正在读取的记录数组的类型,format 参数是一个struct 格式字符串。在一种情况下,格式字符串可能是 ">3H";在另一种情况下,它可能是 ">4s2H";等等。对于上面的结果示例,它是">2H"

fieldNames 参数是给定记录类型中字段名称的字符串序列。对于上面的结果示例,这是 ("glyphID", "paletteIndex")

因此,我逐步遍历缓冲区(字节序列数据),获取顺序切片并一次一个地解包记录,为每条记录创建一个字典并将它们附加到 array 列表.

有没有更好的方法来做到这一点,比如在某个模块中使用 unpack 的方法,允许将格式定义为结构数组并立即解压整个 shebang?

最佳答案

看看开泰- https://kaitai.io/ ,一个用于跨多种语言解析二进制文件的库,具有以独立于语言的方式定义文件格式的框架。

它能够在文件格式中定义条件,并根据需要调整解析。虽然学习曲线并非立即微不足道,但也不是太难。


假设您想自己做而不是使用外部库,需要考虑一些可以提高性能/代码的事情:

  1. 使用struct.unpack_from(format, buffer, offset=0)而不是当前方法,因为 buffer[index : index + recordLength] 可能会创建新对象并复制不需要的内存
  2. 如果你想解包一个相同格式的数组,你可以用struct.iter_unpack(format, buffer)进一步改进它。然后遍历结果:

    import itertools
    import struct

    def tryReadRecordsArrayFromBuffer(buffer, numRecords, format, fieldNames):
    unpack_iter = struct.iter_unpack(buffer, format)
    return [
    # I like this better than dict(zip(...)) but you can also do that
    {k: v for k, v in zip(fieldNames, vals)}
    # We use `islice` to only take the first numRecords values
    for vals in itertools.islice(unpack_iter, numRecords)
    ]

关于Python:从二进制数据中解压结构数组的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62295626/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com