2011-02-07 9 views
27

1つのフォルダ内のサブフォルダを含む.zipからすべてのファイルを抽出しようとしています。サブフォルダからすべてのファイルを元の構造を維持せずに1つのフォルダにのみ抽出したい。現時点では、すべてを抽出し、ファイルをフォルダに移動し、以前のサブフォルダを削除します。同じ名前のファイルは上書きされます。python ZipFileを使用して構造体を保持せずにzipからファイルを抽出しますか?

ファイルを書き込む前に行うことはできますか?ここで

は、例えば構造です:終わり

my_zip/file1.txt 
my_zip/dir1/file2.txt 
my_zip/dir1/dir2/file3.txt 
my_zip/dir3/file4.txt 

私はこれをシューッという音:

my_dir/file1.txt 
my_dir/file2.txt 
my_dir/file3.txt 
my_dir/file4.txt 

私はこのコードに何を追加することができますか?

import zipfile 
my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

zip_file = zipfile.ZipFile(my_zip, 'r') 
for files in zip_file.namelist(): 
    zip_file.extract(files, my_dir) 
zip_file.close() 

私はzip_file.namelistからファイルパスを()名前を変更する場合、私はこのエラーを持っている:

KeyError: "There is no item named 'file2.txt' in the archive" 

答えて

41

を、Fを抽出し、 ilenameをコピーし、それをターゲットファイルにコピーします(サブディレクトリの世話をしないで、ZipFile.extractが動作する方法です)。

import os 
import shutil 
import zipfile 

my_dir = r"D:\Download" 
my_zip = r"D:\Download\my_file.zip" 

with zipfile.ZipFile(my_zip) as zip_file: 
    for member in zip_file.namelist(): 
     filename = os.path.basename(member) 
     # skip directories 
     if not filename: 
      continue 

     # copy file (taken from zipfile's extract) 
     source = zip_file.open(member) 
     target = file(os.path.join(my_dir, filename), "wb") 
     with source, target: 
      shutil.copyfileobj(source, target) 
+0

ありがとうございます – Thammas

7

ちょうど代わりに、メモリ内のバイトに抽出したファイル名を計算し、そこに自分でそれを書く、 ライブラリをさせるのにそれを行う - -mostly、単に「読んで()」の代わりに「解凍()」メソッドを使用します。これは、zipアーカイブのメンバーのファイルハンドルを開き

import zipfile 
import os 

my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

zip_file = zipfile.ZipFile(my_zip, 'r') 
for files in zip_file.namelist(): 
    data = zip_file.read(files, my_dir) 
    # I am almost shure zip represents directory separator 
    # char as "/" regardless of OS, but I don't have DOS or Windos here to test it 
    myfile_path = os.path.join(my_dir, files.split("/")[-1]) 
    myfile = open(myfile_path, "wb") 
    myfile.write(data) 
    myfile.close() 
zip_file.close() 
+0

ありがとう。私は例外を追加してmyfile_pathのディレクトリ\を避け、ファイルを保持しなければなりません。 – Thammas

2

ZipFile.infolist()を反復することは可能です。返されたZipInfoオブジェクトでは、filenameを操作してディレクトリ部分を削除し、最後に指定されたディレクトリに展開することができます。

import glob 
import zipfile 
import shutil 
import os 

my_dir = "D:\\Download\\" 
my_zip = "D:\\Download\\my_file.zip" 

with zipfile.ZipFile(my_zip) as zip: 
    for zip_info in zip.infolist(): 
     if zip_info.filename[-1] == '/': 
      continue 
     zip_info.filename = os.path.basename(zip_info.filename) 
     zip.extract(zip_info, my_dir) 
関連する問題