2012-09-30 63 views
3

所以我在玩維基百科轉儲文件。這是一個已經被壓縮的XML文件。我可以將所有文件寫入目錄,但是當我想要分析時,我必須重新讀取磁盤上的所有文件。這給了我隨機訪問,但速度很慢。我有內存將整個壓縮文件放入內存中。讀取內存映射的bzip2壓縮文件

我可以加載轉儲文件,並讀取所有的行,但我不能在它尋找它,因爲它是巨大的。看起來,bz2庫必須先讀取和捕獲偏移量,然後才能將偏移量帶到那裏(並將其全部解壓縮,因爲偏移量位於解壓縮的字節中)。

無論如何,我試圖mmap的轉儲文件(約9.5演出),並加載到bzip。我顯然想在之前的bzip文件中測試它。

我想映射mmap文件到BZ2File,所以我可以通過它來尋找(獲得一個特定的,無壓縮的字節偏移量),但從看起來,這是不可能的,如果沒有解壓縮整個mmap文件(這會遠遠超過30千兆字節)。

我有什麼選擇嗎?

這是我寫的一些代碼來測試。

import bz2 
import mmap 

lines = '''This is my first line 
This is the second 
And the third 
''' 

with open("bz2TestFile", "wb") as f: 
    f.write(bz2.compress(lines)) 

with open("bz2TestFile", "rb") as f: 
    mapped = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) 

    print "Part of MMAPPED" 
    # This does not work until I hit a minimum length 
    # due to (I believe) the checksums in the bz2 algorithm 
    # 
    for x in range(len(mapped)+2): 
     line = mapped[0:x] 
     try: 
      print x 
      print bz2.decompress(line) 
     except: 
      pass 

# I can decompress the entire mmapped file 
print ":entire mmap file:" 
print bz2.decompress(mapped) 

# I can create a bz2File object from the file path 
# Is there a way to map the mmap object to this function? 
print ":BZ2 File readline:" 
bzF = bz2.BZ2File("bz2TestFile") 

# Seek to specific offset 
bzF.seek(22) 
# Read the data 
print bzF.readline() 

這一切都使我雖然不知道,有什麼特別之處BZ2文件對象,允許其尋求後讀取一條線嗎?它是否必須讀取它之前的每一行才能從算法中獲得校驗和以正確工作?

+0

這是BZ2格式的限制;你不知道文件中的任何東西的大小,直到你解壓那些該死的東西。 –

+1

如果文件是靜態文件,我可以解壓縮一次,獲取我需要的數據,然後使用這些信息來即時解壓縮它?或者我應該嘗試一種不同的壓縮格式? – MercuryRising

+0

我不知道;我會使用'gzip'壓縮,它更適合流媒體和靈活的解壓縮。 –

回答

1

我找到了答案! James Taylor在BZ2文件中編寫了一些腳本,他的腳本位於biopython模塊中。

https://bitbucket.org/james_taylor/bx-python/overview

這些工作得很好,雖然他們不允許尋求在BZ2文件任意字節偏移,他的劇本讀出BZ2數據塊,並允許求基於塊。

具體參見bx-python/wiki/IO/SeekingInBzip2Files

+0

請注意,爲了獲得bzip-table命令,該命令負責將未壓縮的偏移量映射到壓縮的偏移量,您還需要seek-bzip2回購,如[james_taylor/bx-python/issues /#14 - 入門指南:索引MAF - Bitbucket](https://bitbucket.org/james_taylor/bx-python/issues/14/getting-started-indexing-mafs) – nealmcb