如何更新压缩文件中的一个文件?

18

我有这个zip文件结构。

压缩文件名 = filename.zip

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

我想仅更新 index.html。我尝试更新 index.html,但然后在 1.zip 文件中它仅包含 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 文件?


你目前尝试了什么?展示你的代码并描述哪些部分有效,哪些部分无效。 - user1907906
2个回答

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)

请注意,由于ZipFile自2.7起也是上下文管理器,因此在Python 2.6及更早版本中需要使用contextlib。

您可能希望检查您的文件是否实际存在于归档文件中,以避免无用的归档重建。


3
只想说声谢谢,这个脚本对我帮助很大! - Babken Vardanyan
1
我对临时文件的管理有一点不同:首先,from tempfile import NamedTemporaryFile,然后使用临时文件,我只需将函数的其余部分放在 with NamedTemporaryFile() as tmp_file: 中,并获取名称:tmpname = os.path.basename(tmp_file.name)。最后,我不使用 os.rename(...),而是使用 shutil.copyfile(tmpname, filename)。上下文管理器会在最后处理和关闭临时文件。 - zezollo

5

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