Ich versuche, alle Dateien aus .Zip zu extrahieren, die Unterordner in einem Ordner enthalten. Ich möchte, dass alle Dateien aus Unterordnern in nur einem Ordner extrahiert werden, ohne dass die ursprüngliche Struktur erhalten bleibt. Im Moment extrahiere ich alle, verschiebe die Dateien in einen Ordner und entferne dann die vorherigen Unterordner. Die gleichnamigen Dateien werden überschrieben.
Ist es möglich, dies vor dem Schreiben von Dateien zu tun?
Hier ist eine Struktur zum Beispiel:
my_Zip/file1.txt
my_Zip/dir1/file2.txt
my_Zip/dir1/dir2/file3.txt
my_Zip/dir3/file4.txt
Zum Schluss möchte ich Folgendes:
my_dir/file1.txt
my_dir/file2.txt
my_dir/file3.txt
my_dir/file4.txt
Was kann ich zu diesem Code hinzufügen?
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()
wenn ich den Dateipfad von Zip_file.namelist () umbenenne, habe ich diesen Fehler:
KeyError: "There is no item named 'file2.txt' in the archive"
Dadurch werden Dateikennungen der Mitglieder des Zip-Archivs geöffnet, der Dateiname extrahiert und in eine Zieldatei kopiert (so funktioniert ZipFile.extract
, ohne Unterverzeichnisse zu berücksichtigen).
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)
Es ist möglich, die ZipFile.infolist()
zu durchlaufen. Bei den zurückgegebenen ZipInfo
-Objekten können Sie die filename
so bearbeiten, dass der Verzeichnisabschnitt entfernt und schließlich in ein bestimmtes Verzeichnis extrahiert wird.
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)
Extrahieren Sie einfach die Bytes im Speicher, berechnen Sie den Dateinamen und geben Sie ihn selbst dort ein....................................
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()
Ein ähnliches Konzept wie die Lösung von Gerhard Götz , jedoch für das Extrahieren einzelner Dateien anstelle der gesamten Zip-Datei geeignet:
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)))