Overwriting File in Ziparchive

overwriting file in ziparchive

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)

Usage:

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

ZipArchive, I need to create new file and overwrite existing

Just like the error codes in PHP the zip flags are also bitwise additive means you can combine them using OR (|) to do more...

if ($zip->open($packageFileName,  (ZipArchive::CREATE | ZipArchive::OVERWRITE) ))

Above will create a zip if it's not there else will overwrite. So this is how you do your CREATE_OVERWRITE.

How do I overwrite an existing zip file?

See the Remarks in the documentation for ZipFile.Open:

When you set the mode parameter to Create, the archive is opened with FileMode.CreateNew as the file mode value. If the archive already exists, an IOException is thrown.
When you set the mode parameter to Update, the archive is opened with FileMode.OpenOrCreate as the file mode value. If the archive exists, it is opened. The existing entries can be modified and new entries can be created. If the archive does not exist, a new archive is created; however, creating a zip archive in Update mode is not as efficient as creating it in Create mode.

So the problem is down to the underlying File handling. When you use Create as the ZipArchiveMode, the API is implicitly attempting to create a file without handling its already existing. In your case, the Update ZipArchiveMode is probably more appropriate. The FileMode enumeration goes into more detail about what each value mentioned above allows and requires.

That being said, if you are looking to replace an existing archive rather than alter its contents, you will need to check for its existence and delete it if it exists before opening the archive in Create mode.

Overwrite contents of ZipArchiveEntry

Updating the archive means you are either adding, moving or removing an entry from the archive.

Consider doing the following steps.

  • Get the entry content

  • Remove the entry from the archive (take note of name/location)

  • Modify content as desired.

  • Add modified content back to the archive.

How to update one file in a zip archive

From zip(1):

When given the name of an existing zip archive, zip will replace identically named entries in the zip archive or add entries for new names.

So just use the zip command as you normally would to create a new .zip file containing only that one file, except the .zip filename you specify will be the existing archive.

PHP 7 ZipArchive::OVERWRITE not working

Pass ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE as the flag.

It's a bug: https://bugs.php.net/bug.php?id=71064 (since PHP 5.6.16)

There is an issue with the ZipArchive class' open() method. In previous versions of PHP when the only flag passed to the method was the ZipArchive::OVERWRITE, the method also created non-existing archives.

Since PHP 5.6 the OVERWRITE flag alone cannot create new archives which breaks compatibility.

php - What will happen if I overwrite the file itself when it is executing (using ZipArchive)

On Linux files are not usually locked (see https://unix.stackexchange.com/questions/147392/what-is-advisory-locking-on-files-that-unix-systems-typically-employs) so you can do whatever you want with that file. PHP works with that file in memory so you can overwrite it during it's execution.

But if you will run the script multiple times while the first one is in progress it might load incomplete version and then it will throw some error so it might be wise to make sure that won't happen (using locks) or try to do some more atomic approach.

Windows locks files so I assume you won't be able to extract files the same way there.



Related Topics



Leave a reply



Submit