Hallo,
Ich bin mittlerweile auch darauf gekommen, das es nur dadurch möglich ist das zifpile-Modul zu erweitern.
Ich habe die Methode 'zipfile.read' etwas umgebaut.
Folgende Methode kann in eine geerbte Klasse von zipfile.ZipFile übernommen werden. Sie dient dazu, auch große Files eines Archivs mühelos zu entpacken. Der File-Buffer wird dabei nicht komplett dekomprimiert sondern schrittweise.
Code: Alles auswählen
def unzip(self, name, dir):
"""Unzip file and write to defined directory"""
#Checking
if self.mode not in ("r", "a"):
raise RuntimeError, 'read() requires mode "r" or "a"'
if not self.fp:
raise RuntimeError, \
"Attempt to read ZIP archive that was already closed"
#Filename and dir creation
fname = os.path.join(dir, os.path.basename(name))
if not os.path.exists(dir):
os.makedirs(dir)
#Jump to right archiv position and set bufsize
zinfo = self.getinfo(name)
filepos = self.fp.tell()
self.fp.seek(zinfo.file_offset, 0)
if zinfo.compress_size > 1024:
bufsize = zinfo.compress_size / 50
else:
bufsize = zinfo.compress_size
#Start unzip operation
if zinfo.compress_type == zipfile.ZIP_STORED:
#Read bytes from zip archiv name and writing
crc = 0
f = file(fname, "wb")
while f.tell() < zinfo.compress_size:
if bufsize > zinfo.compress_size - f.tell():
bufsize = zinfo.compress_size - f.tell()
bytes = self.fp.read(bufsize)
f.write(bytes)
crc = binascii.crc32(bytes, crc)
self.fp.seek(filepos, 0)
f.close()
elif zinfo.compress_type == zipfile.ZIP_DEFLATED:
#Read bytes from zip archiv name
bytes = self.fp.read(zinfo.compress_size)
self.fp.seek(filepos, 0)
#Checking
if not zlib:
raise RuntimeError, \
"De-compression requires the (missing) zlib module"
#Decopmressing and writing
dc = zlib.decompressobj(-15)
crc = 0
f = file(fname, "wb")
while 1:
bytes = dc.decompress(bytes, bufsize)
f.write(bytes)
crc = binascii.crc32(bytes, crc)
if dc.unconsumed_tail:
bytes = dc.unconsumed_tail
else:
break
#Need to feed in unused pad byte so that zlib won't choke
ex = dc.decompress('Z') + dc.flush()
if ex:
f.write(ex)
crc = binascii.crc32(ex, crc)
f.close()
else:
raise zipfile.BadZipfile, \
"Unsupported compression method %d for file %s" % \
(zinfo.compress_type, name)
#Check CRC
if crc != zinfo.CRC:
raise zipfile.BadZipfile, "Bad CRC-32 for file %s" % name
#Set orginal file date anf file attribute
mtime = time.mktime(zinfo.date_time + (-1, -1, -1))
os.utime(fname, (time.time(), mtime))
Vielleicht hat ja jemand noch Verbesserungsvorschläge!?