2017-02-17 123 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否,因爲我想從'file_subset_list'中僅提取/流僅傳輸_certain_文件 – 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)) 

與Python 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)) 
相關問題