存档一组gzip压缩文件

时间:2016-07-18 15:43:54

标签: python compression gzip tar gzipstream

我有一组大约10个gzip文件,我想将其存档到一个文件中,以便用户下载。我想知道最好的办法是什么。

  1. Gunzip一切,然后将整套文件tar-gz变成myfiles.tar.gz
  2. 将gz文件集转换为myfiles.tar
  3. 选项 1 似乎有不必要的步骤,因为原始文件已经过压缩。

    选项 2 似乎令人困惑,因为没有迹象表明存档中的文件确实已被压缩。

    人们通常如何处理归档一组已经压缩的文件?

    我正在使用Python(如果它很重要),但我正在通过shell执行来执行操作。

2 个答案:

答案 0 :(得分:1)

gzipped tar存档不是压缩文件的存档。它是一个压缩的文件存档。相比之下,zip存档是压缩文件的存档。

如果您希望能够提取(或更新)单个文件,则压缩文件存档是一种更好的存档格式。但它是一种较差的压缩技术;除非组件文件大部分都很大或已经压缩,否则单独压缩文件会导致更多的开销。

由于gzipped tar档案的主要用例是完整存储库的传输,并且整个存档通常一次解压缩,因此无法解压缩和提取单个文件这一事实[注1]并不是很大成本。另一方面,改进的压缩比带来了显着的好处。

要回答这个问题,组合多个gzipped tar档案的唯一方法是解压缩所有这些档案,将它们组合成一个tar档案,然后重新压缩结果;原帖中的选项1

注释

  1. 当然,您可以解压缩整个存档并从解压缩的流中提取单个文件;没有必要保存解压缩的结果。 tar实用程序将透明地执行此操作。但在幕后,存档本身正在解压缩。在不解压缩整个存档的情况下,甚至无法列出gzipped tar存档的内容。

答案 1 :(得分:0)

未压缩文件的压缩存档肯定是您的用户想要的。由于您使用的是Python,因此可以跳过shell并使事情变得更清晰(IMO)。它使用tarfilegzip.GzipFile来处理归档和压缩部分。

编者注:在写这篇文章时,我偶然发现了一个你可能想要注意的有趣错误 - https://blog.nelhage.com/2010/02/a-very-subtle-bug/

from __future__ import with_statement  # god I hope you don't need this
import gzip
import sys
import tarfile
try:
    import io
except ImportError:  # makes things work before Python 3
    import StringIO as io

with tarfile.open(sys.argv[1], mode='w:gz') as archive:
    for name in sys.argv[2:]:
        with gzip.GzipFile(name) as gzip_file:
            buf = io.StringIO()
            buf.write(gzip_file.read())
            buf.seek(0)

            info = archive.gettarinfo(name)
            if info.name.endswith('.gz'):
                info.name = info.name[:-3]
            info.size = buf.len
            archive.addfile(info, fileobj=buf)

现在,如果未压缩的文件 large ,我可能不会这样做,因为它会将每个文件作为块读取到内存中。这很好,因为它保留了文件属性,如perms,times和存档文件中没有的内容。