在Python中解压缩.bz2文件

在Python中解压缩.bz2文件,python,compression,Python,Compression,这是一个看似简单的问题,但我显然很无聊。我有一个从网页下载所有.bz2文件的小脚本,但由于某种原因,该文件的解压缩让我非常头疼 我是个Python新手,所以答案可能很明显,请帮助我 在脚本的这一部分中,我已经有了这个文件,我只想把它读入一个变量,然后解压缩它?是这样吗?我已经尝试了各种方法来实现这一点,我通常会在这段代码的最后一行出现“ValueError:找不到流的结尾”错误。我试着打开zipfile并以无数种不同的方式将其写入字符串。这是最新的 openZip = open(zipFile,

这是一个看似简单的问题,但我显然很无聊。我有一个从网页下载所有.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文件而感到无比沉重


顺便说一句,使用7zip手动对其进行解压缩,以确保文件不会出现问题或其他任何问题,并且解压良好。

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

uncompressedData = bz2.BZ2File(zipFile).read()
似乎更接近你想要的

编辑:OP展示了他尝试过的更多东西(尽管我没有看到任何关于尝试过最好方法的注释——我上面推荐的一行!),但它们似乎都有一个共同的错误,我重复上面的关键点:

开场白。。。压缩后的文件 这是一个文本文件。。。不是

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

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

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

因此,我怀疑OP是在使用Windows,并为没有小心地使用
'rb'
选项(“读取二进制文件”)来打开
内置的
而付出了代价。(尽管无论您使用的是什么平台,
bz2.BZ2File
仍然更简单!)

openZip=open(zipFile,“r”)

如果您在Windows上运行,您可能需要在此处说openZip=open(zipFile,“rb”),因为文件可能包含CR/LF组合,并且您不希望对其进行翻译

newLine=openZip.readline()

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

s=fileHandle.read(1024) [...] 解压数据+=bz2。解压

出于同样的原因,这是错误的。1024字节的块对解压器来说可能意义不大,因为解压器需要使用自己的块大小

s=fileHandle.read() 解压数据=bz2。解压

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

这非常有用。 在Windows open上,2300个文件中有44个出现文件结尾丢失错误。 添加b(inary)标志以打开修复了该问题

for line in bz2.BZ2File(filename, 'rb', 10000000) :
效果很好。(10M是缓冲大小,适用于所涉及的大文件)


谢谢

你好,Alex,谢谢你的快速回复,请查看我的问题中针对你评论的编辑。因此,此方法的问题是,虽然它似乎可以很好地解压缩,但当我尝试运行它时,文件不知何故已损坏。当我用7zip打开.bz2文件时,它运行良好。此外,正确提取的文件(带有7zip)的大小是948kb,而从我的脚本中提取的文件是952KB。我完全搞不懂。7zip除了bz2之外还接受许多其他格式,也许您的文件是其他格式之一。如果法律和隐私不妨碍这一点,把它放在一个公共URL上,给我URL,我会让你知道它的格式和如何解码——没有文件在手,这对我来说基本上是不可能的。谢谢你的帮助,Alex,很抱歉这里有点厚。这是有道理的,但是为什么python bz2库会解压缩该文件呢?它不会引发某种异常吗?我将查看是否可以找到放置该文件的位置(这并不违法,它只是Team Fortress 2映射文件(.bsp文件)的.bz2文件,但我不想公开这个URL,因为它是我朋友的服务器托管的。我如何检查.bz2文件是否真的在bz2文件中?但你说它确实引发了一个异常--一个值错误!我相信你只能在下载一个bzip2文件--如果这个exe正确解码了文件,我相信,这应该证明它是正确的bz2,反之亦然。你真的试过亚历克斯的建议吗?谢谢,这很有帮助。