我有一组大约10个gzip文件,我想将其存档到一个文件中,以便用户下载。我想知道最好的办法是什么。
myfiles.tar.gz
?myfiles.tar
。 选项 1 似乎有不必要的步骤,因为原始文件已经过压缩。
选项 2 似乎令人困惑,因为没有迹象表明存档中的文件确实已被压缩。
人们通常如何处理归档一组已经压缩的文件?
我正在使用Python(如果它很重要),但我正在通过shell执行来执行操作。
答案 0 :(得分:1)
gzipped tar存档不是压缩文件的存档。它是一个压缩的文件存档。相比之下,zip存档是压缩文件的存档。
如果您希望能够提取(或更新)单个文件,则压缩文件存档是一种更好的存档格式。但它是一种较差的压缩技术;除非组件文件大部分都很大或已经压缩,否则单独压缩文件会导致更多的开销。
由于gzipped tar档案的主要用例是完整存储库的传输,并且整个存档通常一次解压缩,因此无法解压缩和提取单个文件这一事实[注1]并不是很大成本。另一方面,改进的压缩比带来了显着的好处。
要回答这个问题,组合多个gzipped tar档案的唯一方法是解压缩所有这些档案,将它们组合成一个tar档案,然后重新压缩结果;原帖中的选项1 。
tar
实用程序将透明地执行此操作。但在幕后,存档本身正在解压缩。在不解压缩整个存档的情况下,甚至无法列出gzipped tar存档的内容。答案 1 :(得分:0)
未压缩文件的压缩存档肯定是您的用户想要的。由于您使用的是Python,因此可以跳过shell并使事情变得更清晰(IMO)。它使用tarfile和gzip.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和存档文件中没有的内容。