【问题标题】:Python's zipfile module cannot update entries [duplicate]Python的zipfile模块无法更新条目[重复]
【发布时间】:2013-02-19 22:10:04
【问题描述】:

我想使用 pythons zipfile 模块更新 zip 文件中的条目。 我的问题是这会生成一个新条目。

请假设我有这个代码:

from zipfile import ZipFile,ZIP_DEFLATED
with ZipFile("myfile.zip","w") as z:
    z.writestr("hello.txt", "the content of hello.txt", ZIP_DEFLATED)
    ###  how to update the hello.txt file here ?
    z.writestr("hello.txt", "the content of hello.txt", ZIP_DEFLATED)

在此之后,实际的 zip 文件有两个条目而不是一个:

$ unzip -l myfile.zip 
Archive:  myfile.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       24  2013-02-19 22:48   hello.txt
       24  2013-02-19 22:48   hello.txt
---------                     -------
       48                     2 files
$ python --version
Python 3.3.0
$

我知道编写一个完整的新文件的方法,但这会 如果内容很大,要花很多时间。

zip(1) 实用程序可以做到这一点(使用“-u”选项),那么为什么不使用 python 呢? 有什么方法我仍然可以使用 python 实现这一点?

谢谢

【问题讨论】:

    标签: python zipfile


    【解决方案1】:

    zip 格式没有任何简单的方法可以删除或替换存档中的文件。可能有一些图书馆可以就地这样做,但我不知道有哪一个。

    等一下:

    zip(1) 完全可以做到这一点(使用“-u”选项),那么为什么不使用 python?

    首先,-u 所做的只是告诉它“仅在时间戳不是较新的情况下替换现有文件”,这在这里并不重要。如果没有-u,它仍然会,默认命令是add,它在不检查时间戳的情况下执行相同的操作:

    更新现有条目并添加新文件。如果存档不存在,请创建它。这是默认模式。

    但是,更重要的是,正如the manpage you referenced 明确所说:

    压缩文件。更改现有 zip 存档时,zip 将使用新内容写入一个临时文件,并且仅在创建新版本的过程完成且没有错误时替换旧文件。

    这正是您想要做的:将一个完整的新文件写入一个临时位置,然后用新文件替换原始文件。

    如果您需要让它在 Windows 上运行,这可能会有点痛苦。 (如果没有,请使用tempfile.NamedTemporaryFileos.rename。)但是您已经知道该怎么做:

    我知道写一个完整的新文件的方法,但是如果内容很大,这将花费很多时间。

    不会比zip -u 花费太多时间。

    【讨论】:

    • 很好的答案,谢谢。我希望 zip(1) 正在修改文件而不是创建新文件。因此,即使 zip 也没有提供修改文件的方法,那么 python 也不会。
    • @dnagy:很少有 Unix 风格的工具可以修改文件。即使它不是更简单,写临时和重命名仍然总是更安全。这样,如果出现错误,您仍然拥有原始文件,而不是截断或无法恢复的损坏垃圾。
    【解决方案2】:

    我怀疑zipfile 模块可以根据需要修改档案。如果可以的话,会有一种从ZipFile 中删除文件的方法,但目前还没有。

    【讨论】:

    • 它在我看来更像是一个错误。如果我使用命令行 zip(1) 工具,我永远无法在存档中获得两次相同的条目。
    • 你认为这是一个想要的 API 还是他们根本没有实现那些方法(还)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 2011-12-13
    • 1970-01-01
    • 2018-11-26
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多