使用bz2.BZ2Decompressor

时间:2018-03-30 06:18:38

标签: python-3.x compression

我在Windows 10上使用Fall Creators更新运行Python 3.6.4。我正在尝试解压缩维基媒体数据转储文件,特别是https://dumps.wikimedia.org/enwiktionary/latest/enwiktionary-latest-pages-meta-current.xml.bz2

此文件在命令行上使用7z进行解压缩但没有问题,但在Python解压缩程序输出长度为零的第一个数据块上失败。代码如下:

import bz2

def decompression(qin,                 # Iterable supplying input bytes data
                  qout):               # Pipe to next process - needs bytes data
    decomp = bz2.BZ2Decompressor()     # Create a decompressor
    for chunk in qin:                  # Loop obtaining data from source iterable
        lc = len(chunk)                # = 16384
        dc = decomp.decompress(chunk)  # Do the decompression
        ldc = len(dc)                  # = 0
        qout.put(dc)                   # Pass the decompressed chunk to the next process

我已经验证了bz2标头是有效的,并且由于文件使用命令行实用程序解压缩没有问题,因此问题似乎与BZ2的Python实现有关。解压缩器中的以下值似乎正常,并且与文档中的预期相符。

eof = False
unused_data = b''
needs_input = True

有关如何解决此问题的任何建议?

1 个答案:

答案 0 :(得分:1)

打败我。我发现你的功能没有任何问题。以下工作在链接的.bz2文件上没有问题,其中输出完全匹配该.bz2文件的命令行解压缩的结果:

import sys
import bz2

def decompression(qin,                 # Iterable supplying input bytes data
                  qout):               # Pipe to next process - needs bytes data
    decomp = bz2.BZ2Decompressor()     # Create a decompressor
    for chunk in qin:                  # Loop obtaining data from source iterable
        lc = len(chunk)                # = 16384
        dc = decomp.decompress(chunk)  # Do the decompression
        # qout.put(dc)                   # Pass the decompressed chunk to the next process
        qout.write(dc)

with open('enwiktionary-latest-pages-meta-current.xml.bz2', 'rb') as f:
    it = iter(lambda: f.read(16384), b'')
    decompression(it, sys.stdout.buffer)

我只对您的函数进行了一次微不足道的更改,以便将结果写入stdout。我使用的是Python 3.6.4。我也尝试使用Python 2.7.10(删除.buffer),它再次完美无缺。

你真的只是让你的功能运行吗?你是什​​么意思"在第一个区块失败"?前几次调用(本例中为七次)实际上不会返回任何解压缩数据,因为您尚未提供完整的块来进行处理。但是没有报道错误。

注意:要对包含串联bzip2流的.bz2文件执行此操作,您需要在eof上循环为true,创建一个新的解压缩器对象并从前一个解压缩程序中输入unused_data对象,后跟从压缩文件中读取的更多数据。链接文件不是其中之一。