2015-10-15 58 views
1

我想用已知的头文件和长度解析Python中的原始二进制文件。解析多组视频帧的原始二进制文件

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

该文件遵循以下规则分开的帧:

  • 字节1:指示信道#(例如取0xE0,0xE1,0xE2 ...)
  • 字节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的大。将每个频道解析为单独文件的最佳方式是什么?另外,如何一次批量处理多个文件,并根据输入名称保存文件?

回答

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什么明智的块,而不是一下子
  • 要小心字节VS字符串(不同的处理上的Python 2.x的3.x的VS)
  • 如果您需要了解更多关于开放,阅读,和写文件,随时发布更具体的问题

就批处理服务器al文件,你最好的选择是multiprocessing模块。它需要一段时间来让你的头,但之后,它很容易使用。

+0

你会建议在C++中使用什么? – user2079221

+0

我从来没有在C++中广泛使用过iostreams,因此我个人可能会在C中使用它,并使用带有unsigned char(byte)缓冲区的fopen(),fread()。一次读取64KB或1MB的东西。 –