con - descomprimir rar python
Eliminar archivo de archivo zip con el Módulo ZipFile (3)
El siguiente fragmento funcionó para mí (elimina todos los archivos * .exe de un archivo Zip):
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()
Si lees todo en la memoria, puedes eliminar la necesidad de un segundo archivo. Sin embargo, este fragmento recomprime todo.
Después de una inspección más cercana, ZipInfo.header_offset
es el desplazamiento desde el inicio del archivo. El nombre es engañoso, pero el encabezado Zip principal en realidad se almacena al final del archivo. Mi editor hexadecimal lo confirma.
De modo que el problema con el que se encontrará es el siguiente: también debe eliminar la entrada del directorio en el encabezado principal o apuntará a un archivo que ya no existe. Dejar el encabezado principal intacto podría funcionar si mantiene el encabezado local del archivo que está eliminando también, pero no estoy seguro de eso. ¿Cómo lo hiciste con el módulo anterior?
Sin modificar el encabezado principal me sale un error "falta X bytes en el archivo zip" cuando lo abro. Esto podría ayudarlo a descubrir cómo modificar el encabezado principal.
La única forma en que surgió para eliminar un archivo de un archivo comprimido fue crear un archivo zip temporal sin el archivo que se debe eliminar y luego cambiarle el nombre al nombre del archivo original.
En python 2.4, la clase ZipInfo tenía un atributo file_offset
, por lo que era posible crear un segundo archivo comprimido y copiar los datos a otro archivo sin descomprimir / recomprimir.
Este file_offset
falta en Python 2.6, entonces ¿hay alguna otra opción que crear otro archivo comprimido descomprimiendo cada archivo y luego recomprimiéndolo nuevamente?
¿Existe alguna forma directa de eliminar un archivo en el archivo zip, busqué y no encontré nada?
La rutina delete_from_zip_file
de ruamel.std.zipfile
¹ le permite eliminar un archivo basado en su ruta completa dentro del ZIP, o en base a ( re
) patrones. Por ejemplo, puede eliminar todos los archivos .exe
de test.zip
usando
from ruamel.std.zipfile import delete_from_zip_file
delete_from_zip_file(''test.zip'', pattern=''.*.exe'')
(Por favor, tenga en cuenta el punto antes del *
).
Esto funciona de forma similar a la solución de mdm (incluida la necesidad de recompresión), pero recrea el archivo ZIP en la memoria (utilizando la clase InMemZipFile()
), sobrescribiendo el archivo anterior una vez que se ha leído por completo.
¹ Descargo de responsabilidad: soy el autor de ese paquete.
No muy elegante, pero así es como lo hice:
import subprocess
import zipfile
z = zipfile.ZipFile(zip_filename)
files_to_del = filter( lambda f: f.endswith(''exe''), z.namelist()]
cmd=[''zip'', ''-d'', zip_filename] + files_to_del
subprocess.check_call(cmd)
# reload the modified archive
z = zipfile.ZipFile(zip_filename)