如何更新zip文件中的一个文件?

18 投票
2 回答
35333 浏览
提问于 2025-04-20 14:42

我有一个压缩文件的结构。

压缩文件名是 filename.zip

filename>    images>
             style.css
             default.js
             index.html

我想只更新 index.html 文件。我尝试更新 index.html,但结果是压缩包里只剩下了 index.html 这个文件,其他文件都被删掉了。

这是我尝试过的代码:

import zipfile

msg = 'This data did not exist in a file before being added to the ZIP file'
zf = zipfile.ZipFile('1.zip', 
                     mode='w',
                     )
try:
    zf.writestr('index.html', msg)
finally:
    zf.close()
    
print zf.read('index.html')

那么我该如何用Python只更新 index.html 文件呢?

2 个回答

5

你不能直接更新一个已经存在的文件。你需要先读取你想要编辑的文件,然后创建一个新的压缩包,这个压缩包里要包含你编辑过的文件和原来压缩包里的其他文件。

下面是一些可能对你有帮助的问题。

如何使用ZipFile模块从压缩文件中删除文件

如何在压缩档案中覆盖文件

如何在压缩档案中删除或替换文件

36

在ZIP文件中更新一个文件是不支持的。你需要先把这个文件从压缩包里去掉,然后再把更新后的版本添加进去,重新打包。

import os
import zipfile
import tempfile

def updateZip(zipname, filename, data):
    # generate a temp file
    tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname))
    os.close(tmpfd)

    # create a temp copy of the archive without filename            
    with zipfile.ZipFile(zipname, 'r') as zin:
        with zipfile.ZipFile(tmpname, 'w') as zout:
            zout.comment = zin.comment # preserve the comment
            for item in zin.infolist():
                if item.filename != filename:
                    zout.writestr(item, zin.read(item.filename))

    # replace with the temp archive
    os.remove(zipname)
    os.rename(tmpname, zipname)

    # now add filename with its new data
    with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf:
        zf.writestr(filename, data)

msg = 'This data did not exist in a file before being added to the ZIP file'
updateZip('1.zip', 'index.html', msg)

需要注意的是,如果你使用的是Python 2.6或更早的版本,你需要用到contextlib,因为从2.7版本开始,ZipFile才支持上下文管理。

你可能还想先检查一下你的文件在压缩包里是否真的存在,这样可以避免不必要的重新打包。

撰写回答