Comment décompresser des fichiers très volumineux en python?
-
19-08-2019 - |
Question
À l'aide de python 2.4 et de la bibliothèque ZipFile
intégrée, je ne peux pas lire de très gros fichiers zip (plus de 1 ou 2 Go) car il veut stocker l'intégralité du contenu du fichier non compressé . Existe-t-il un autre moyen de le faire (avec une bibliothèque tierce ou un autre hack), ou dois-je "shell out"? et décompressez-le de cette façon (ce qui n'est pas aussi multi-plateforme, évidemment).
La solution
Voici un aperçu de la décompression de gros fichiers.
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()
Autres conseils
A partir de Python 2.6, vous pouvez utiliser ZipFile .open ()
pour ouvrir un handle de fichier sur un fichier et copier efficacement le contenu dans un fichier cible de votre choix:
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)
Ceci utilise shutil.copyfileobj ()
pour lire efficacement les données de l'objet zipfile ouvert, en les copiant dans le fichier de sortie.