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 theZipArchive::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
Convert Python Strings into Floats Explicitly Using the Comma or the Point as Separators
Multiprocessing VS Multithreading VS Asyncio in Python 3
How to Isolate Everything Inside of a Contour, Scale It, and Test the Similarity to an Image
Python: Sort Function Breaks in the Presence of Nan
How to Replace Back Slash Character with Empty String in Python
Python: How to Run Eval() in the Local Scope of a Function
Downloading a Directory Tree with Ftplib
How to Access a Standard-Library Module in Python When There Is a Local Module with the Same Name
What's a Good Equivalent to Subprocess.Check_Call That Returns the Contents of Stdout
Weird Behavior: Lambda Inside List Comprehension
Matrix Multiplication in Pure Python
Factorize a Column of Strings in Pandas
How to Set Ticks on Fixed Position , Matplotlib
Generating Sublists Using Multiplication ( * ) Unexpected Behavior
Removing Horizontal Lines in Image (Opencv, Python, Matplotlib)
Split an Integer into Digits to Compute an Isbn Checksum
Seeking from End of File Throwing Unsupported Exception
Error: Pg_Config Executable Not Found When Installing Psycopg2 on Alpine in Docker