Conseguido!!
A partir de esta información:
http://stackoverflow.com/questions/297345/create-a-zip-file-from-a-generator-in-python/2734156#2734156
He creado esta implementación, os la dejo por si alguno le interesara:
import time, shutil
from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
import zlib, binascii, struct
class ZipWriter(object):
def __init__(self, zf, filename):
self.zf = zf
self.filename = filename
self.zinfo = self._ZipInfo(filename)
self.file_size = 0
self.compress_size = 0
self.CRC = 0
if self.zinfo.compress_type == ZIP_DEFLATED:
self.cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
zlib.DEFLATED, -15)
else:
self.cmpr = None
def _ZipInfo(self, filename):
zinfo = ZipInfo(filename=filename,
date_time=time.localtime(time.time())[:6])
zinfo.compress_type = self.zf.compression
zinfo.external_attr = 0600 << 16
zinfo.file_size = 0
zinfo.flag_bits = 0x00
zinfo.CRC = 0
zinfo.compress_size = 0
zinfo.header_offset = self.zf.fp.tell() # Start of header bytes
self.zf._writecheck(zinfo)
self.zf._didModify = True
self.zf.fp.write(zinfo.FileHeader())
return zinfo
def write(self, bytes):
self.file_size = self.file_size + len(bytes)
self.CRC = binascii.crc32(bytes, self.CRC)
if self.cmpr:
bytes = self.cmpr.compress(bytes)
self.compress_size = self.compress_size + len(bytes)
self.zf.fp.write(bytes)
def close(self):
if self.cmpr:
buf = cmpr.flush()
self.compress_size = self.compress_size + len(buf)
self.zf.fp.write(buf)
self.zinfo.compress_size = self.compress_size
else:
self.zinfo.compress_size = self.file_size
self.zinfo.CRC = self.CRC
self.zinfo.file_size = self.file_size
position = self.zf.fp.tell()
self.zf.fp.seek(self.zinfo.header_offset + 14, 0)
self.zf.fp.write(struct.pack("<lLL", self.zinfo.CRC,
self.zinfo.compress_size, self.zinfo.file_size))
self.zf.fp.seek(position, 0)
self.zf.filelist.append(self.zinfo)
self.zf.NameToInfo[self.zinfo.filename] = self.zinfo
def copyZipFile(source, target):
zsource = ZipFile(source, "r")
ztarget = ZipFile(target, "w")
for item in zsource.infolist():
fsrc = zsource.open(item.filename, "r")
fdst = ZipWriter(ztarget, item.filename)
shutil.copyfileobj(fsrc, fdst)
fdst.close()
fsrc.close()
zsource.close()
ztarget.close()
Saludos
Juande
El 24/01/2011 23:29, Juan de Dios Manjón Pérez escribió:
Andrey,
también he llegado al punto que comentas,
el problema que tengo ahora es para escribir el chuck, ya que
ZipFile.open(name, mode='r', pwd=None) no admite mode='w'.
El unico metodo ZipFile.writestr(zinfo_or_arcname, bytes) que he
encontrado para escribir requiere que se escriba TODO de golpe.
La implementación que busco es parecida a:
from zipfile import ZipFile
from shutil import copyfileobj
def copyZipFile(source, target):
zsource = ZipFile(source,"r")
ztarget = ZipFile(target,"w")
for item in zsource.infolist():
fsrc = zsource.open(item.filename,"r")
fdst = ztarget.open(item.filename,"w") #mode no acepta "w".
exception
copyfileobj(fsrc,fdst)
fdst.close()
fsrc.close()
zsource.close()
ztarget.close()
Saludos
Juande
El 24/01/2011 20:14, Andrey Antoukh escribió:
http://docs.python.org/py3k/library/zipfile.html
ZipFile.open(name, mode='r', pwd=None)
Extract a member from the archive as a file-like object (ZipExtFile).
name is the name of the file in the archive, or a ZipInfo object. The
mode parameter, if included, must be one of the following: 'r' (the
default), 'U', or 'rU'. Choosing 'U' or 'rU' will enable universal
newline support in the read-only object. pwd is the password used for
encrypted files. Calling open() on a closed ZipFile will raise a
RuntimeError.
Note The file-like object is read-only and provides the following
methods: read(), readline(), readlines(), __iter__(), __next__().
Lo que a groso modo quiere decir que devuelve un objeto fichero que
tiene todos los métodos estándares para leer. De lo que se deduce que
podemos leerlos a cachitos para que no ocupe memoria.
La implementación seria parecida a la que ya se ha propuesto. O como
el simple ejemplo...
>>> zipobj = zipfile.ZipFile("prueba.zip", "r")
>>> for zip in zipobj.namelist():
... zipfileobj = zipobj.open(zip, "r")
... for chuck in zipfileobj:
... # lo que sea que tengas que hacer con estos datos.
Un saludo.
_______________________________________________
Python-es mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/
_______________________________________________
Python-es mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/