password - ¿Cómo descomprimes archivos muy grandes en Python?
zipfile python (2)
Al usar Python 2.4 y la biblioteca ZipFile
, no puedo leer archivos zip muy grandes (más de 1 o 2 GB) porque quiere almacenar todo el contenido del archivo descomprimido en la memoria. ¿Hay alguna otra forma de hacer esto (ya sea con una biblioteca de terceros o algún otro hack), o debo "pagar" y descomprimirlo de esa manera (que no es tan multiplataforma, obviamente).
Aquí hay un resumen de la descompresión de archivos grandes.
import zipfile
import zlib
import os
src = open( doc, "rb" )
zf = zipfile.ZipFile( src )
for m in zf.infolist():
# Examine the header
print m.filename, m.header_offset, m.compress_size, repr(m.extra), repr(m.comment)
src.seek( m.header_offset )
src.read( 30 ) # Good to use struct to unpack this.
nm= src.read( len(m.filename) )
if len(m.extra) > 0: ex= src.read( len(m.extra) )
if len(m.comment) > 0: cm= src.read( len(m.comment) )
# Build a decompression object
decomp= zlib.decompressobj(-15)
# This can be done with a loop reading blocks
out= open( m.filename, "wb" )
result= decomp.decompress( src.read( m.compress_size ) )
out.write( result )
result = decomp.flush()
out.write( result )
# end of the loop
out.close()
zf.close()
src.close()
A partir de Python 2.6, puede usar ZipFile.open()
para abrir un identificador de archivo en un archivo y copiar contenido de manera eficiente en un archivo de destino de su elección:
import errno
import os
import shutil
import zipfile
TARGETDIR = ''/foo/bar/baz''
with open(doc, "rb") as zipsrc:
zfile = zipfile.ZipFile(zipsrc)
for member in zfile.infolist():
target_path = os.path.join(TARGETDIR, member.filename)
if target_path.endswith(''/''): # folder entry, create
try:
os.makedirs(target_path)
except (OSError, IOError) as err:
# Windows may complain if the folders already exist
if err.errno != errno.EEXIST:
raise
continue
with open(target_path, ''wb'') as outfile, zfile.open(member) as infile:
shutil.copyfileobj(infile, outfile)
Esto usa shutil.copyfileobj()
para leer datos de manera eficiente desde el objeto zipfile abierto, copiándolo en el archivo de salida.