2012-09-30 64 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