2009-08-17 28 views
3

我需要在一個二進制文件中處理幾十千兆字節的數據。數據文件中的每條記錄都是可變長度的。任何從大型二進制文件讀取數據的有效方法?

所以該文件是這樣的:

<len1><data1><len2><data2>..........<lenN><dataN> 

的數據包含整數,指針,雙值等。

我發現python甚至無法處理這種情況。如果我在內存中讀取整個文件,沒有任何問題。它很快。但看起來struct包不擅長性能。它幾乎堅持解開字節。

任何幫助表示讚賞。

謝謝。

+0

請提供一些關於你在做什麼結構是如此糟糕的暗示。 – 2009-08-17 14:02:20

+0

你確定你正在讀取內存中的數十GB數據嗎? – 2009-08-17 14:25:42

+0

「struct」的性能問題真的存在嗎,還是僅僅需要很長時間?即使採用最高效的代碼,處理數十千兆字節的數據也需要一段時間... – 2009-08-17 15:34:55

回答

4

structarray,其他答案建議,對於實現的細節都很好,如果您的需要總是按順序讀取所有文件或其前綴,則可能是您需要的全部內容。其他選項包括buffer,mmap,甚至ctypes,這取決於您沒有提及的確切需求的許多細節。如果沒有合適的和可訪問的庫(在C,C++,Fortran等中)已經存在,那麼爲了處理這個龐大文件的目的,可以使用一些專門的Cython編碼助手提供所需的所有額外性能:你需要。

但顯然這裏有奇特的問題 - 一個數據文件怎麼可以包含指針,例如,它在本質上是關係到解決內存一個什麼概念?他們可能是「抵消」,而且,如果是這樣,他們究竟是如何建立和編碼的?你的需求是否比簡單的順序閱讀(比如隨機訪問)更先進?如果是這樣,你可以做第一次「索引」傳遞,以獲得從文件開始到開始記錄的所有偏移量到更有用的緊湊,手動格式化的輔助文件? (偏移量的二進制文件對於array是很自然的 - 除非偏移量需要比您的機器上的array支持更長!)。記錄長度和構成的分佈以及構成「幾十千兆字節」的記錄數量是多少?等等等等。

你有一個非常大的規模問題(毫無疑問,非常大規模的硬件來支持它,因爲你提到你可以很容易地讀取所有的文件到內存中,這意味着一個64位的盒子有幾十GB的RAM - 哇!),所以它是非常值得詳細的照顧,以優化其處理 - 但我們不能幫助這麼詳細的護理,除非我們知道足夠的細節這樣做!)。

2

看看array模塊,具體是array.fromfile的方法。此位:

數據文件中的每條記錄都是可變長度。

是相當不幸的。但你可以用try-except從句來處理它。

2

對於類似的任務,我這樣定義一個類:

class foo(Structure): 
     _fields_ = [("myint", c_uint32)] 

創建一個實例

bar = foo() 

,做,

block = file.read(sizeof(bar)) 
memmove(addressof(bar), block, sizeof(bar)) 

在可變尺寸的情況下,記錄,您可以使用類似的方法檢索lenN,然後讀取相應的數據條目。似乎微不足道的實施。然而,我不知道這種方法與使用pack()unpack()相比有多快,也許其他人已經對兩種方法進行了剖析。

1

如果您使用dump數據文件到內存中的sqlite3中該怎麼辦。

import sqlite3 
sqlite3.Connection(":memory:") 

然後,您可以使用sql來處理數據。

此外,你可能想看看generators(或here)和iterators(或herehere)。

+0

假設數據是可變長度,那麼這些行將不會被標準化以用於數據庫。 – hughdbrown 2009-08-17 17:36:26

2

有關解析文件而不將其讀入內存的幫助,您可以使用bitstring模塊。

在內部,這是使用struct模塊和一個bytearray,但是一個不可變的Bits對象可以用一個文件名來初始化,所以它不會將它全部讀入內存。

例如:

from bitstring import Bits 

s = Bits(filename='your_file') 
while s.bytepos != s.length: 
    # Read a byte and interpret as an unsigned integer 
    length = s.read('uint:8') 
    # Read 'length' bytes and convert to a Python string 
    data = s.read(length*8).bytes 
    # Now do whatever you want with the data 

當然你也可以將數據分析不過你想要的。

您還可以使用切片符號來讀取文件內容,但請注意,索引將以位爲單位而不是字節,因此例如s[-800:]將是最後的100個字節。

1

PyTables是一個非常好的圖書館處理HDF5,天文學和氣象學用於處理非常大的數據集的二進制格式:

它的工作原理或多或少像一個層次型數據庫,你可以在裏面存儲多個表格。看看它。