1つのフォルダーにサブフォルダーを含む.Zipからすべてのファイルを抽出しようとしました。サブフォルダーのすべてのファイルを、元の構造を保持せずに1つのフォルダーのみに抽出する必要があります。現時点では、すべてを抽出し、ファイルをフォルダーに移動してから、以前のサブフォルダーを削除します。同じ名前のファイルは上書きされます。
ファイルを書き込む前にそれを行うことは可能ですか?
以下に例を示します。
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"
これにより、Zipアーカイブのメンバーのファイルハンドルが開き、ファイル名が抽出されてターゲットファイルにコピーされます(そのように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 = open(os.path.join(my_dir, filename), "wb")
with source, target:
shutil.copyfileobj(source, target)
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)
メモリ内のバイトに抽出し、ファイル名を計算し、ライブラリに実行させるのではなく、自分で書き込みます--ほとんどの場合、「extract()」メソッドの代わりに「read()」を使用します
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()
GerhardGötzのソリューション と同様の概念ですが、Zip全体ではなく単一のファイルを抽出するように適合されています。
with ZipFile(zipPath, 'r') as zipObj:
zipInfo = zipObj.getinfo(path_in_Zip))
zipInfo.filename = os.path.basename(destination)
zipObj.extract(zipInfo, os.path.dirname(os.path.realpath(destination)))