Delete file from zipfile with the ZipFile Module Delete file from zipfile with the ZipFile Module python python

Delete file from zipfile with the ZipFile Module


The following snippet worked for me (deletes all *.exe files from a Zip archive):

zin = zipfile.ZipFile ('archive.zip', 'r')zout = zipfile.ZipFile ('archve_new.zip', 'w')for item in zin.infolist():    buffer = zin.read(item.filename)    if (item.filename[-4:] != '.exe'):        zout.writestr(item, buffer)zout.close()zin.close()

If you read everything into memory, you can eliminate the need for a second file. However, this snippet recompresses everything.

After closer inspection the ZipInfo.header_offset is the offset from the file start. The name is misleading, but the main Zip header is actually stored at the end of the file. My hex editor confirms this.

So the problem you'll run into is the following: You need to delete the directory entry in the main header as well or it will point to a file that doesn't exist anymore. Leaving the main header intact might work if you keep the local header of the file you're deleting as well, but I'm not sure about that. How did you do it with the old module?

Without modifying the main header I get an error "missing X bytes in zipfile" when I open it. This might help you to find out how to modify the main header.


Not very elegant but this is how I did it:

import subprocessimport zipfilez = zipfile.ZipFile(zip_filename)files_to_del = filter( lambda f: f.endswith('exe'), z.namelist()]cmd=['zip', '-d', zip_filename] + files_to_delsubprocess.check_call(cmd)# reload the modified archivez = zipfile.ZipFile(zip_filename)


The routine delete_from_zip_file from ruamel.std.zipfile¹ allows you to delete a file based on its full path within the ZIP, or based on (re) patterns. E.g. you can delete all of the .exe files from test.zip using

from ruamel.std.zipfile import delete_from_zip_filedelete_from_zip_file('test.zip', pattern='.*.exe')  

(please note the dot before the *).

This works similar to mdm's solution (including the need for recompression), but recreates the ZIP file in memory (using the class InMemZipFile()), overwriting the old file after it is fully read.


¹ Disclaimer: I am the author of that package.