2017-02-17 1 views
2

Mon but est d'extraire certains fichiers de l'archive Zip et de les transférer directement vers un autre Zip sans avoir à effectuer d'extraction intermédiaire sur le disque.Extraire le fichier du ZIP directement vers un autre ZIP

Jusqu'à présent, j'ai:

from zipfile import ZipFile, ZIP_DEFLATED 


def stream_conents(src_zip, dst_zip, file_subset_list): 
    with ZipFile(src_zip, "r", compression=ZIP_DEFLATED) as src_zip_archive: 
     with ZipFile(dst_zip, "w", compression=ZIP_DEFLATED) as dst_zip_archive: 
      for zitem in src_zip_archive.namelist(): 
       if zitem in file_subset_list: 
        zitem_object = src_zip_archive.open(zitem) 
        dst_zip_archive.write(zitem_object, zitem,) 

Mais il se contente de TypeError: argument should be string, bytes or integer, not ZipExtFile

+0

Ne pouvez-vous pas simplement copier le fichier zip? – Okx

+0

@Okx non, car je veux extraire/diffuser uniquement les _certains_ fichiers de 'file_subset_list' – Vasily

Répondre

2

Vous pouvez lire le fichier en mémoire et utiliser writestr pour écrire l'archive.

def stream_conents(src_zip, dst_zip, file_subset_list): 
    with ZipFile(src_zip, "r", compression=ZIP_DEFLATED) as src_zip_archive: 
     with ZipFile(dst_zip, "w", compression=ZIP_DEFLATED) as dst_zip_archive: 
      for zitem in src_zip_archive.namelist(): 
       if zitem in file_subset_list: 
        # warning, may blow up memory 
        dst_zip_archive.writestr(zitem, 
         src_zip_archive.read(zitem)) 

A partir de python 3.6, ZipFile.open ouvrira les fichiers d'archive en mode écriture. Cela vous permet d'écrire le fichier en morceaux et de réduire l'utilisation globale de la mémoire.

def stream_conents(src_zip, dst_zip, file_subset_list): 
    with ZipFile(src_zip, "r", compression=ZIP_DEFLATED) as src_zip_archive: 
     with ZipFile(dst_zip, "w", compression=ZIP_DEFLATED) as dst_zip_archive: 
      for zitem in src_zip_archive.namelist(): 
       if zitem in file_subset_list: 
        if sys.version_info >= (3, 6): 
         with src_zip_archive.open(zitem) as from_item: 
          with dst_zip_archive.open(zitem, "w") as to_item: 
           shutil.copyfileobj(from_item, to_item) 
        else: 
         # warning, may blow up memory 
         dst_zip_archive.writestr(zitem, 
          src_zip_archive.read(zitem))