2017-02-17 5 views
2

Моя цель - извлечь определенные файлы из Zip-архива и передать их прямо в другой ZIP без необходимости выполнять промежуточное извлечение на диск.Извлечь файл из ZIP прямо в другой ZIP

До сих пор у меня есть:

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,) 

Но он просто бросает TypeError: argument should be string, bytes or integer, not ZipExtFile

+0

Не можете ли вы просто скопировать zip-файл? – Okx

+0

@Okx нет, потому что я хочу извлечь/передать только _certain_ файлы из 'file_subset_list' – Vasily

ответ

2

Вы можете прочитать весь файл в память и использовать writestr для записи в архив.

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)) 

Начиная с питоном 3.6 ZipFile.open будет открывать файлы архива в режиме записи. Это позволяет записывать файл в куски и уменьшать использование общей памяти.

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)) 
Смежные вопросы