读取内存映射的bzip2压缩文件

时间:2012-09-30 09:02:17

标签: python mmap bzip2

所以我正在玩维基百科转储文件。这是一个已被bzip压缩的XML文件。我可以将所有文件写入目录,但是当我想进行分析时,我必须重新读取磁盘上的所有文件。这给了我随机访问,但它很慢。我有ram将整个bzipped文件放入ram。

我可以很好地加载转储文件并读取所有行,但我不能在其中寻找,因为它是巨大的。从它看起来,bz2库必须先读取并捕获偏移量,然后才能将它带到那里(并将其全部解压缩,因为偏移量是以解压缩的字节为单位)。

无论如何,我正在尝试mmap转储文件(~9.5 gigs)并将其加载到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文件对象有什么特别之处,它允许它在搜索之后读取一行?它是否必须先读取每行才能使算法中的校验和正确运行?

1 个答案:

答案 0 :(得分:1)

我找到了答案! James Taylor在BZ2文件中编写了几个用于搜索的脚本,他的脚本位于biopython模块中。

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

这些工作非常好,虽然他们不允许在BZ2文件中寻找任意字节偏移,但他的脚本会读出BZ2数据块并允许基于块进行搜索。

请特别参阅bx-python / wiki / IO / SeekingInBzip2Files