Python" gzip"如果压缩扩展不是" .gz"

时间:2018-01-28 16:04:01

标签: python compression gzip

我需要使用gzip模块压缩文件,但输出文件扩展名可能不是.gz

看看这个简单的代码:

import gzip
import shutil

input_path = "test.txt"
output_path = input_path + ".gz"

with open(input_path, 'w') as file:
    file.write("abc" * 10)

with gzip.open(output_path, 'wb') as f_out:
    with open(input_path, 'rb') as f_in:
        shutil.copyfileobj(f_in, f_out)

工作正常。但是,如果我将".gz"替换为".gzip",那么我无法正确打开压缩文件:

Uncompressing not working

我尝试使用7-Zip和WinRar,结果是一样的,即使我重命名该文件,错误仍然存​​在。

有人知道问题来自哪里吗?

我尝试使用压缩bz2lzma,无论扩展名是什么,它们似乎都能正常工作。

2 个答案:

答案 0 :(得分:3)

你实际上有两种版本的文件:

首先,.gz文件:

with gzip.open("test.txt.gz", 'wb') as f_out:
    with open("test.txt", 'rb') as f_in:
        shutil.copyfileobj(f_in, f_out)

其次,.gzip档案:

with gzip.open("test.txt.gzip", 'wb') as f_out:
    with open("test.txt", 'rb') as f_in:
        shutil.copyfileobj(f_in, f_out)

两者都创建了一个GZIP,其中包含test.txt。唯一的区别是,在第二种情况下,test.txt被重命名为test.txt.gzip

问题是gzip.open的参数实际上有两个目的:gzip存档的文件名文件的内部文件名(bad design,imho)。

因此,如果您执行gzip.open("abcd", 'wb')并写入,它将创建名为abcd的gzip存档,其中包含一个名为abcd的文件。

然而,有魔力:如果文件名以.gz结尾,那么它的行为会有所不同,例如: gzip.open("bla.gz", 'wb')创建一个名为bla.gz的gzip存档,其中包含一个名为bla的文件。

所以,.gz你激活了(没有记载,据我所知!)魔法,而.gzip却没有激活。

答案 1 :(得分:1)

可以通过使用gzip.GzipFile构造函数而不是gzip.open方法来控制档案内部的文件名。然后gzip.GzipFile需要一个单独的os.open调用。

with open(output_path, 'wb') as f_out_gz:
    with gzip.GzipFile(fileobj=f_out_gz, filename=input_path, mode='wb') as f_out: 
    ...
    f_out.flush()

还要注意添加的f_out.flush()-根据我的经验,GzipFile在某些情况下可能会在关闭文件之前随机不刷新数据,从而导致存档损坏。

或作为完整示例:

import gzip
import shutil

input_path = "test.txt"
output_path = input_path + ".gz"

with open(input_path, 'w') as file:
    file.write("abc" * 10)

with open(output_path, 'wb') as f_out_gz:
    with gzip.GzipFile(fileobj=f_out_gz, filename=input_path, mode='wb') as f_out
        with open(input_path, 'rb') as f_in:
            shutil.copyfileobj(f_in, f_out)
            f_out.flush()