2015-10-15 57 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的東西。 –