在Python中将多个zip文件合并成一个zip文件

16

我有多个具有相同结构的zip文件--它们在根级别包含XML文件。每个zip文件中的所有文件都是唯一的(跨zip文件没有重复项)。我需要将所有zip文件中的所有XML文件组合成一个单独的zip文件(与原始zip文件具有相同的结构)。有什么最好的建议吗?谢谢。


3
把它们全部拆开然后制作一个新的? - sarnold
3
那将是最明显的方法。您还可以选择一个作为最终的压缩文件,从其他文件中提取文件并将其添加到最终文件中,但不确定它是否会更快。 - jgritty
谢谢@sarnold。我也在考虑这种方法,但不确定是否有更优雅的方式来实现它。 - Dave Crumbacher
@jgritty,你的想法很有趣。我想我可以做一个测试,看看是否有性能提升。 - Dave Crumbacher
2个回答

14
这是我能想到的最简短的版本:

这是我能想到的最简短的版本:

>>> import zipfile as z
>>> z1 = z.ZipFile('z1.zip', 'a')
>>> z2 = z.ZipFile('z2.zip', 'r')
>>> z1.namelist()
['a.xml', 'b.xml']
>>> z2.namelist()
['c.xml', 'd.xml']
>>> [z1.writestr(t[0], t[1].read()) for t in ((n, z2.open(n)) for n in z2.namelist())]
[None, None]
>>> z1.namelist()
['a.xml', 'b.xml', 'c.xml', 'd.xml']
>>> z1.close()

如果没有测试其他方法,对我来说这是最好的解决方案(也可能是最明显的!),因为假设两个zip文件包含相同数量的数据,则此方法仅需要对其中一半(1个文件)进行解压缩和重新压缩。

PS:列表推导式只是为了在控制台上将指令保持在一行上(可以加速调试)。良好的Pythonic代码需要一个适当的for循环,因为生成的列表没有任何用处...

希望有所帮助!


谢谢,虽然我会有数量不同的zip文件,所以我需要一个更通用的方法。 - Dave Crumbacher
2
@DaveCrumbacher:除非我误解了你的意思,要将此方法用于合并多个文件,你只需添加一个循环即可:for zfile in (z2, z3, z4, ...)……或者是我漏掉了什么? - mac

12

由于@mac的帮助,我得出了下面这个结果。需要注意的是,当前的实现方式会修改第一个zip文件,使其包含其他zip文件中所有的文件。

import zipfile as z

zips = ['z1.zip', 'z2.zip', 'z3.zip']

"""
Open the first zip file as append and then read all
subsequent zip files and append to the first one
"""
with z.ZipFile(zips[0], 'a') as z1:
    for fname in zips[1:]:
        zf = z.ZipFile(fname, 'r')
        for n in zf.namelist():
            z1.writestr(n, zf.open(n).read())

5
zipfile.ZipFile()也是一个上下文管理器,因此您可以将z1.close()替换为with z.ZipFile(zips[0], 'a') as z1:并缩进随后的代码。读取对象时也一样。 - glglgl
3
谢谢@glglgl。我已经更新了我的答案以反映这种方法。 - Dave Crumbacher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接