Python的zipfile模块无法更新条目[重复]

Posted

技术标签:

【中文标题】Python的zipfile模块无法更新条目[重复]【英文标题】:Python's zipfile module cannot update entries [duplicate] 【发布时间】: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 实现这一点?

谢谢

【问题讨论】:

【参考方案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 还是他们根本没有实现那些方法(还)?

以上是关于Python的zipfile模块无法更新条目[重复]的主要内容,如果未能解决你的问题,请参考以下文章

修改 zipfile 条目的文件内容

Python zipfile:RuntimeError:文件密码错误

python模块之ZipFile

python模块 zipfile

从 Python zipfile 读取是线程安全的吗?

python3中zipfile模块的常用方法