为什么BZip2文件允许从文件末尾查找,而Gzip文件不允许?
问题
我正在用 Python 2.7.6 处理一些很大的压缩文件,想在开始之前知道解压后的文件大小。我尝试使用这个回答中提到的第二种方法。这个方法对 bzip2 格式的文件有效,但对 gzip 格式的文件就不行。那这两种压缩算法有什么不同,导致这种情况呢?
示例代码
下面这段代码展示了这个问题,假设你在当前工作目录下有 "test.bz2" 和 "test.gz" 这两个文件:
import os
import bz2
import gzip
bz = bz2.BZ2File('test.bz2', mode='r')
bz.seek(0, os.SEEK_END)
bz.close()
gz = gzip.GzipFile('test.gz', mode='r')
gz.seek(0, os.SEEK_END)
gz.close()
运行后会出现以下错误信息:
错误追踪(最近的调用在最前面):
文件 "zip_test.py",第 10 行,
gz.seek(0, os.SEEK_END)
文件 "/usr/lib64/python2.6/gzip.py",第 420 行,
引发 ValueError('不支持从末尾查找')
ValueError: 不支持从末尾查找
为什么这个方法对 *.bz2 文件有效,但对 *.gz 文件就不行呢?
1 个回答
4
简单来说,gzip是一种流压缩工具,这意味着每个被压缩的部分都依赖于前面的部分。如果你想在文件中间查找某个位置,那是没用的,因为整个文件都得解压缩才能找到你要的内容。可能gzip.py的作者认为,直接报错比默默解压文件要好,这样用户就能意识到查找是没效率的。
而bzip2则是块压缩工具,每个块都是独立的。
如果你真的想对一个gzipped文件进行随机访问,那就得写一个包装器,先解压内容,然后返回一个可以查找的缓冲区。不过这样做就失去了你在问题链接中提到的优化效果。