2008-11-17 11 views

Respuesta

31

versión adaptada de the script es:

#!/usr/bin/env python 
from __future__ import with_statement 
from contextlib import closing 
from zipfile import ZipFile, ZIP_DEFLATED 
import os 

def zipdir(basedir, archivename): 
    assert os.path.isdir(basedir) 
    with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z: 
     for root, dirs, files in os.walk(basedir): 
      #NOTE: ignore empty directories 
      for fn in files: 
       absfn = os.path.join(root, fn) 
       zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path 
       z.write(absfn, zfn) 

if __name__ == '__main__': 
    import sys 
    basedir = sys.argv[1] 
    archivename = sys.argv[2] 
    zipdir(basedir, archivename) 

Ejemplo:

C:\zipdir> python -mzipdir c:\tmp\test test.zip 

Se crea 'C:\zipdir\test.zip' archivo con los contenidos del directorio 'c:\tmp\test'.

+0

'ZFN = absfn [len (basedir) + len (os.sep):] 'por qué no' absbasedir = os.path.abspath (basedir); os.path.relpath (absfn, absbasedir) '? Además, la longitud de basedir y os.sep puede verse como constante, por lo que debería estar fuera de los dos bucles for. – n611x007

+0

nunca escuché hablar de [contextlib.closing] (http://docs.python.org/2/library/contextlib.html#contextlib.closing) antes, pero hace que la declaración * con * sea compatible con versiones anteriores de ** 2.5 ** . Anteriormente me encontré con un error con ... el "con [instrucción] del futuro";), porque algunas funciones stdlib no admitían * con * en * 2.5 * (incluso si la instrucción misma funcionaba con la importación), mientras lo soporta en * 2.7 *. Supongo que esto podría evitarse con 'closing'. – n611x007

+0

Utilicé esta solución pero tuve que modificar la siguiente línea: zfn = absfn [len (basedir) + len (os.sep):] y restar uno a la posición como: zfn = absfn [len (basedir) + len (os.sep) -1:] de lo contrario, el nombre del archivo tiene una letra que falta – jfosoriot

5

Aquí está una versión recursiva

def zipfolder(path, relname, archive): 
    paths = os.listdir(path) 
    for p in paths: 
     p1 = os.path.join(path, p) 
     p2 = os.path.join(relname, p) 
     if os.path.isdir(p1): 
      zipfolder(p1, p2, archive) 
     else: 
      archive.write(p1, p2) 

def create_zip(path, relname, archname): 
    archive = zipfile.ZipFile(archname, "w", zipfile.ZIP_DEFLATED) 
    if os.path.isdir(path): 
     zipfolder(path, relname, archive) 
    else: 
     archive.write(path, relname) 
    archive.close() 
Cuestiones relacionadas