在Python中解压缩.bz2文件

时间:2009-08-09 05:01:43

标签: python compression

所以,这是一个看似简单的问题,但我显然非常沉闷。我有一个小脚本从网页下载所有的.bz2文件,但由于某种原因,解压缩该文件给我带来了严重的问题。

我是一个Python新手,所以答案很明显,请帮助我。

在脚本的这一部分,我已经有了这个文件,我只是想把它读出来一个变量,然后解压缩?是对的吗?我已经尝试了各种方法来做到这一点,我通常在这个片段的最后一行得到“ValueError:找不到流的结尾”错误。我试图打开zipfile并以无数种方式将其写入字符串。这是最新的。

openZip = open(zipFile, "r")
s = ''
while True:
    newLine = openZip.readline()
    if(len(newLine)==0):
       break
    s+=newLine
    print s                   
    uncompressedData = bz2.decompress(s)

嗨Alex,我应该列出我尝试过的所有其他方法,因为我尝试过read()方式。

方法A:

print 'decompressing ' + filename

fileHandle = open(zipFile)
uncompressedData = ''

while True:            
    s = fileHandle.read(1024)
    if not s:
        break
        print('RAW "%s"', s)
        uncompressedData += bz2.decompress(s)

        uncompressedData += bz2.flush()

        newFile = open(steamTF2mapdir + filename.split(".bz2")[0],"w")
        newFile.write(uncompressedData)
        newFile.close()   

我收到错误:

uncompressedData += bz2.decompress(s)
ValueError: couldn't find end of stream

方法B

zipFile = steamTF2mapdir + filename
print 'decompressing ' + filename
fileHandle = open(zipFile)

s = fileHandle.read()
uncompressedData = bz2.decompress(s)

同样的错误:

uncompressedData = bz2.decompress(s)
ValueError: couldn't find end of stream

非常感谢你的回复。我真的把头靠在墙上,因为无法解压缩简单的.bz2文件而感觉非常厚。

通过by,使用7zip手动解压缩,以确保文件没有任何问题,并且解压缩得很好。

3 个答案:

答案 0 :(得分:14)

您正在打开并读取压缩文件,就像它是由行组成的文本文件一样。别!不是。

uncompressedData = bz2.BZ2File(zipFile).read()

似乎更接近你所追求的目标。

编辑:OP已经展示了一些他尝试过的东西(虽然我没有看到任何有关尝试过最佳方法的说明 - 我上面推荐的单线程!)但是他们似乎都有一个共同的错误,我重复上面的关键位:

  

打开...压缩文件好像   它是一个文本文件......它不是。

open(filename)甚至更明确的open(filename, 'r')打开,用于阅读文本文件 - 压缩文件是二进制文件,因此,为了正确阅读,您必须使用open(filename, 'rb')打开它。 ((我的推荐bz2.BZ2File知道它正在处理一个压缩文件,当然,所以没有必要再告诉它了))。

在Python 2.*中,在Unix-y系统上(即除了Windows之外的所有系统),你可以匆匆使用open(但在Python 3.*你可以' t,因为文本是Unicode,而二进制是字节 - 不同的类型。)

在Windows中(以及之前在DOS中),因为Windows的文本文件由于历史原因而区分,所以始终是必不可少的(使用两个字节而不是一个到结束行,并且至少在某些情况下,取一个值为'\0x1A'的字节表示文件的逻辑结尾),因此读写低级代码必须进行补偿。

所以我怀疑OP正在使用Windows并且正在为不小心使用'rb'选项(“读取二进制”)来支付open内置的价格。 (尽管bz2.BZ2File仍然比较简单,无论你使用什么平台! - 。)。

答案 1 :(得分:9)

  

openZip = open(zipFile,“r”)

如果你在Windows上运行,你可能想在这里说 openZip = open(zipFile,“rb”),因为该文件很可能包含CR / LF组合,你不要不希望他们被翻译。

  

newLine = openZip.readline()

正如Alex指出的那样,这是非常错误的,因为“行”的概念对于压缩流来说是陌生的。

  

s = fileHandle.read(1024)   [...]   uncompressedData + = bz2.decompress(s)

出于同样的原因,这是错误的。 1024字节的块对解压缩程序来说不太可能有多大意义,因为它会想要使用它自己的块大小。

  

s = fileHandle.read()   uncompressedData = bz2.decompress(s)

如果这不起作用,我会说这是我上面提到的新线翻译问题。

答案 2 :(得分:5)

这非常有帮助。 在Windows打开时,2300个文件中的44个文件丢失了文件。 添加b(inary)标志以打开问题。

for line in bz2.BZ2File(filename, 'rb', 10000000) :

运作良好。 (10M是缓冲大小,适用于所涉及的大文件)

谢谢!