1

我正在尝试在 Python 中解析具有已知标头和长度的原始二进制文件。

数据是6通道多路复用视频。

该文件遵循以下规则来分隔帧:

  • 字节 1:表示通道号(例如 0xE0、0xE1、0xE2 ...)
  • Bytes 4 & 5:代表图像数据的长度
  • 字节 6:长度:图像数据
  • 图像数据的末尾用 0xFF 填充,以便每个图像块从 16 字节行中的第一个字节开始。

图像数据的开始

E0 01 00 00 D2 59 80 C1 27 3F EC BB 31 7B 3F EC 

BB 31 7B 0F 9B 90 5D A8 81 AA 5F A9 C1 D2 4B B9

9D 0A 8D 1B 8F 89 44 FF 4E 86 92 AD 00 90 5B A8

图像数据结束

67 49 0B B5 BC 82 38 AE 5E 46 49 86 6A FF 24 97 

69 8C 6F 17 6D 67 B5 11 C7 E5 FB E3 3F 65 1F 22 

5C F3 7C D0 7C 49 2F CD 26 37 4D 40 FF FF FF FF

源文件有几 GB 大。将每个通道解析为单独文件的最佳方法是什么?另外,如何一次批处理多个文件,根据输入名称保存文件?

4

1 回答 1

0

解析小块的多 GB 二进制文件可能不是 Python 能够很快完成的事情,因为它需要大量的函数调用和对象创建,这意味着大量的 RAM 和 CPU 开销。如果您需要更高的性能或对内存管理的控制,最好使用较低级别的语言(C、C++、Go、Rust)来执行此操作。

但是,您可以使用struct模块在 Python 中执行此类操作,如下所示:

header = struct.Struct('>BBBH')
data = b'\xE0\x01\x00\x00\xD2\x59\x80...'  # read this from input file
view = memoryview(data)
offset = 0
while offset < len(data):
    channel, _, _, length = header.unpack(view[offset:offset + header.size])
    write_output(channel, view[header.size:header.size + length])
    offset += length

注意事项:

  • 确定长度是大端还是小端(<vs>格式字符串)
  • 使用memoryview是一种避免一些额外的对象复制和创建的方法——希望它可以提高效率
  • 你会想要保持输出文件打开——我刚刚把它隐藏在write_output()上面
  • 如果输入是多 GB,您可能希望以 1MB 的块或其他合理的方式读取输入文件,而不是一次全部读取
  • 注意字节与字符串(Python 2.x 与 3.x 的不同处理方式)
  • 如果您需要了解有关打开、读取和写入文件的更多信息,请随时发布更具体的问题

至于一次批处理多个文件,最好的选择是多处理模块。了解一下确实需要一段时间,但之后使用起来非常简单。

于 2015-10-15T17:21:31.100 回答