我在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
有关如何解决此问题的任何建议?
答案 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
对象,后跟从压缩文件中读取的更多数据。链接文件不是其中之一。