覆盖ziparchive中的文件 [英] overwriting file in ziparchive

查看:45
本文介绍了覆盖ziparchive中的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 archive.zip 和两个文件:hello.txtworld.txt

I have archive.zip with two files: hello.txt and world.txt

我想用带有该代码的新文件覆盖 hello.txt 文件:

I want to overwrite hello.txt file with new one with that code:

import zipfile

z = zipfile.ZipFile('archive.zip','a')
z.write('hello.txt')
z.close()  

但它不会覆盖文件,它以某种方式创建了 hello.txt 的另一个实例 — 看看 winzip 屏幕截图:

but it won't overwrite file, somehow it creates another instance of hello.txt — take a look at winzip screenshot:

既然没有像 zipfile.remove() 这样的方法,那么处理这个问题的最佳方法是什么?

Since there is no smth like zipfile.remove(), what's the best way to handle this problem?

推荐答案

python zipfile 模块无法做到这一点.您必须创建一个新的 zip 文件,然后重新压缩第一个文件中的所有内容以及新修改的文​​件.

There's no way to do that with python zipfile module. You have to create a new zip file and recompress everything again from the first file, plus the new modified file.

下面是一些代码来做到这一点.但请注意,它效率不高,因为它会先解压缩所有数据,然后再重新压缩.

Below is some code to do just that. But note that it isn't efficient, since it decompresses and then recompresses all data.

import tempfile
import zipfile
import shutil
import os

def remove_from_zip(zipfname, *filenames):
    tempdir = tempfile.mkdtemp()
    try:
        tempname = os.path.join(tempdir, 'new.zip')
        with zipfile.ZipFile(zipfname, 'r') as zipread:
            with zipfile.ZipFile(tempname, 'w') as zipwrite:
                for item in zipread.infolist():
                    if item.filename not in filenames:
                        data = zipread.read(item.filename)
                        zipwrite.writestr(item, data)
        shutil.move(tempname, zipfname)
    finally:
        shutil.rmtree(tempdir)

用法:

remove_from_zip('archive.zip', 'hello.txt')
with zipfile.ZipFile('archive.zip', 'a') as z:
    z.write('hello.txt')

这篇关于覆盖ziparchive中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆