我有几个gz文件,其解压缩似乎无法正常工作。我选择了其中一个,该文件位于本地文件夹中,并且来自外部来源。我不知道压缩过程。
我创建了一个python脚本来说明这种情况。为了有一个参考文件进行测试,我解压缩了gz文件,然后再次对其进行了压缩(在Ubuntu上使用gzip),以在我的计算机中生成相同的gz文件。这两个文件表现出不同的行为:
import gzip
import zlib
import hashlib
def md5(content):
m = hashlib.md5()
m.update(content)
return m.hexdigest()
def decompress_gzip_size(file_name):
with gzip.open(file_name, 'rb') as f_out:
f_content = f_out.read()
print(len(f_content), file_name)
print (md5(f_content), file_name)
def decompress_open_gzip_size(file_name):
with open(file_name, 'rb') as f_out:
f_content = f_out.read()
unzip_content = gzip.decompress(f_content)
print(len(unzip_content), file_name)
print (md5(unzip_content), file_name)
def decompress_zlib_size(file_name):
with open(file_name, 'rb') as f_out:
f_content = f_out.read()
unzip_content = zlib.decompress(f_content, 32)
print(len(unzip_content), file_name)
print (md5(unzip_content), file_name)
def decompress_zlib_obj(file_name):
decompress_obj = zlib.decompressobj(32)
with open(file_name, 'rb') as f_out:
f_content = f_out.read()
unzip_content = decompress_obj.decompress(f_content)
print(len(unzip_content), file_name)
print(len(decompress_obj.unused_data), 'Unused data')
print (md5(unzip_content), file_name)
external_file = 'external_source_compress.gz'
my_file = 'my-compress-file.gz'
print("decompress_gzip_size")
decompress_gzip_size(my_file)
decompress_gzip_size(external_file)
print("*" * 60)
print("decompress_open_gzip_size")
decompress_open_gzip_size(my_file)
decompress_open_gzip_size(external_file)
print("*" * 60)
print("decompress_zlib_size")
decompress_zlib_size(my_file)
decompress_zlib_size(external_file)
print("*" * 60)
print("decompress_zlib_obj")
decompress_zlib_obj(my_file)
decompress_zlib_obj(external_file)
print("*" * 60)
执行输出为:
decompress_gzip_size
167019534 my-compress-file.gz
a4dd17dd28b89f0b2c300b607cd1a8ba my-compress-file.gz
167019534 external_source_compress.gz
a4dd17dd28b89f0b2c300b607cd1a8ba external_source_compress.gz
************************************************************
decompress_open_gzip_size
167019534 my-compress-file.gz
a4dd17dd28b89f0b2c300b607cd1a8ba my-compress-file.gz
167019534 external_source_compress.gz
a4dd17dd28b89f0b2c300b607cd1a8ba external_source_compress.gz
************************************************************
decompress_zlib_size
167019534 my-compress-file.gz
a4dd17dd28b89f0b2c300b607cd1a8ba my-compress-file.gz
33408639 external_source_compress.gz
4f51ccc64a7baab5ee5e2ce31e816409 external_source_compress.gz
### SIZES AND MD5 DO NOT MATCH ###
************************************************************
decompress_zlib_obj
167019534 my-compress-file.gz
0 Unused data
a4dd17dd28b89f0b2c300b607cd1a8ba my-compress-file.gz
33408639 external_source_compress.gz
46765202 Unused data
4f51ccc64a7baab5ee5e2ce31e816409 external_source_compress.gz
### THERE IS SOME UNUSED DATA IN THE ORIGINAL FILE ###
************************************************************
注意:如果窗口大小参数不是32,则zlib解压缩失败。
不设置窗口大小就会发生这种情况:
Traceback (most recent call last):
File "decompress_python.py", line 53, in <module>
decompress_zlib_size(my_file)
File "decompress_python.py", line 26, in decompress_zlib_size
unzip_content = zlib.decompress(f_content)
zlib.error: Error -3 while decompressing data: incorrect header check
可以看出。如果没有32窗口大小的脚本,脚本将崩溃,但是如果使用32窗口大小的脚本,脚本将完成,但是读取的字节数只是实际数据量的一部分。
文件内部只有一个元素:
gzip -l external_source_compress.gz
compressed uncompressed ratio uncompressed_name
58609586 33410520 -75.4% external_source_compress
有人可以帮助我了解这里发生的事情吗?我真的迷路了。预先感谢。
答案 0 :(得分:2)
Florian的答案几乎肯定是正在发生的事情,这就是您仅部分解压缩的gzip文件必须具有多个成员。要解压缩下一个成员,只需从unused_data
对象获取decompressobj
并开始另一个解压缩。重复该操作,直到使用完所有输入为止。
This answer显示了在python中处理具有多个成员的gzip文件的示例。
听起来wbits
参数应该使用31,而不是32。31期望使用gzip包装器而不是zlib包装器。不指定wbits
会导致解压缩器期望使用zlib包装器,这就是为什么它不适用于您的gzip流。
答案 1 :(得分:1)
gzip流可以包含多个独立压缩的项目,然后将它们简单地连接在一起。期望gzip样式的解压缩器透明地读取所有独立压缩的部分,从而产生单个输出流(基本上忽略内部流结束指示符)。
zlib.compressobj
的文档中没有说明,但是它将在第一个zlib检测到的内部流末尾停止。然后可以独立处理其余数据。在某些应用程序中(但不是您的应用程序),它甚至可能不是zlib压缩的数据。