
In Python can SIE Dateien komprimieren und entpacken, dh Dateien in eine ZIP-Datei komprimieren und eine ZIP-Datei mit dem Zipfile-Modul extrahieren.
Außerdem can SIE ein Verzeichnis (Ordner) einfach komprimieren und eine ZIP-Datei mit make_archive() und unpack_archive() des Shutil-Moduls entpacken.
Beide sind in der Standardbibliothek enthalten, sodass keine zusätzliche Installation erforderlich ist.
Dieser Artikel hat folgenden Inhalt.
- Zippen Sie ein Verzeichnis (Ordner):
shutil.make_archive()
- Entpacken Sie eine Datei:
shutil.unpack_archive()
- Grundlagen des Zipfile-Moduls:
ZipFile objects
- Komprimieren Sie einzelne Dateien in einer ZIP-Datei
- Fügen Sie einer vorhandenen ZIP-Datei weitere Dateien hinzu
- Überprüfen Sie die Liste der Dateien in einer ZIP-Datei
- Einzelne Dateien aus einer ZIP-Datei extrahieren
- Lesen Sie Dateien in einer ZIP-Datei
- ZIP mit Passwörtern (Verschlüsselung und Entschlüsselung)
Zippen Sie ein Verzeichnis (Ordner):shutil.make_archive()
Sie können ein Verzeichnis (Ordner) komprimieren, dh mit shutdown.make_archive() eine ZIP-Datei aus einem Verzeichnis erstellen.
Der erste Parameter base_name ist der Pfad ohne Erweiterung der zu erstellenden ZIP-Datei, der zweite Parameter format ist das Archivformat (‚zip‘, ‚tar‘, ‚gztar‘, ‚bztar‘, ‚xztar‘) und der dritte Parameter root_dir ist der Pfad des zu komprimierenden Verzeichnisses.
Angenommen, es gibt im aktuellen Verzeichnis ein Verzeichnis dir_zip mit following der Struktur.
dir_zip
├── dir_sub
│ └── file_sub.txt
└── file.txt
Komprimieren Sie dieses Verzeichnis in einer ZIP-Datei archive_shutil.zip im aktuellen Verzeichnis.
import shutil
shutil.make_archive('archive_shutil', format='zip', root_dir='dir_zip')
In diesem Fall ist das angegebene Verzeichnis dir_zip selbst nicht in archive_shutil.zip enthalten.
Wenn SIE das Verzeichnis selbst einbinden möchten, geben SIE im dritten Parameter root_dir den Pfad des oberen Verzeichnisses des Zielverzeichnisses und im vierten Parameter base_dir den relativen Pfad des Zielverzeichnisses von root_dir an.
shutil.make_archive('archive_shutil_base', format='zip',
root_dir='.', base_dir='dir_zip')
Siehe den nächsten Abschnitt für das Ergebnis des Entpackens.
Entpacken Sie eine Datei:shutil.unpack_archive()
Sie können eine Datei entpacken, dh den gesamten Inhalt einer ZIP-Datei mit shutdown.unpack_archive() extrahieren.
Der erste Parameter filename ist der Pfad der ZIP-Datei und der zweite Parameter extract_dir ist der Pfad des Zielverzeichnisses, in das das Archiv extrahiert wird.
shutil.unpack_archive('archive_shutil.zip', 'dir_out')
Es wird wie folgt aufgebaut:
dir_out
├── dir_sub
│ └── file_sub.txt
└── file.txt
Obwohl die Dokumentation dies nicht angibt, scheint es ein neues Verzeichnis zu erstellen, selbst wenn extract_dir nicht vorhanden ist (bestätigt in Python 3.9.9).
Die von shutdown.make_archive() mit base_dir erstellte ZIP-Datei wird wie folgt extrahiert:
shutil.unpack_archive('archive_shutil_base.zip', 'dir_out_base')
dir_out_base
└── dir_zip
├── dir_sub
│ └── file_sub.txt
└── file.txt
Grundlagen des Zipfile-Moduls:ZipFile objects
Das Zipfile-Modul stellt die ZipFile-Klasse zum Erstellen, Lesen, Schreiben, Anhängen und Aufhören einer ZIP-Datei bereit.
ZipFile-Objekte werden erstellt, indem der erste Parameter file (Pfad einer ZIP-Datei) und der zweite Parametermodus (read ‚r‘, write ‚w‘, append ‚a‘, etc.) an den Konstruktor zipfile.ZipFile() übergeben werden.
Das ZipFile-Objekt muss mit der close()-Methode geschlossen werden, aber wenn Sie die with-Anweisung verwenden, wird es automatisch geschlossen, wenn der Block beendet ist.
Die Verwendung ähnelt dem Lesen und Schreiben von Dateien mit der eingebauten Funktion open(), z. B. das Festlegen des Modus und die Verwendung der with-Anweisung.
Spezifische Beispiele werden in den following Abschnitten beschrieben.
Komprimieren Sie einzelne Dateien in einer ZIP-Datei
Um einzelne Dateien in eine ZIP-Datei zu komprimieren, erstellen Sie ein neues ZipFile-Objekt und fügen die zu komprimierenden Dateien mit der Methode write() hinzu.
Geben Sie mit zipfile.ZipFile() als erste Parameterdatei den Pfad einer neu erstellten ZIP-Datei an und setzen Sie den zweiten Parametermodus auf ‚w‘ (write).
Im Write-Modus können Sie mit den Parametern Compression und Compresslevel auch die Komprimierungsmethode und -stufe festlegen.
Die Komprimierungsverfahrenskomprimierung ist wie folgt; BZIP2 und LZMA haben ein höheres Komprimierungsverhältnis, aber die Komprimierung dauert länger.
- zipfile.ZIP_STORED: Keine Komprimierung (Standard)
- zipfile.ZIP_DEFLATED: Übliche ZIP-Komprimierung
- zipfile.ZIP_BZIP2: BZIP2-Komprimierung
- zipfile.ZIP_LZMA: LZMA-Komprimierung
Bei ZIP_DEFLATED entspricht die Komprimierungsstufe compresslevel der Stufe von zlib.compressobj(). Standard ist -1 (Z_DEFAULT_COMPRESSION).
level ist die Komprimierungsstufe – eine Ganzzahl von 0 bis 9 oder -1. Ein Wert von 1 (Z_BEST_SPEED) ist am schnellsten und höchstens die geringste Komprimierung, während ein Wert von 9 (Z_BEST_COMPRESSION) am langsamsten ist und am meisten erhöht. 0 (Z_NO_COMPRESSION) ist keine Komprimierung. Der Standardwert ist -1 (Z_DEFAULT_COMPRESSION). Z_DEFAULT_COMPRESSION stellt einen Standardkompromiss zwischen Geschwindigkeit und Komprimierung dar (derzeit gleichwertig mit Stufe 6).
zlib.compressobj() – Komprimierung kompatibel mit gzip – Dokumentation zu Python 3.10.2
Die write()-Methode des ZipFile-Objekts schreibt die Datei mit dem ersten Parameter filename in eine ZIP-Datei und gibt ihr den Archivnamen (= Name in ZIP) second Parameter arcname. Wenn Bogenname weggelassen WIRD, WIRD Dateiname als Archivname verwendet. Sie können eine Verzeichnisstruktur für arcname angeben.
import zipfile
with zipfile.ZipFile('archive_zipfile.zip', 'w',
compression=zipfile.ZIP_DEFLATED,
compresslevel=9) as zf:
zf.write('dir_zip/file.txt', arcname='file.txt')
zf.write('dir_zip/dir_sub/file_sub.txt', arcname='dir_sub/file_sub.txt')
Sie können auch eine Komprimierungsmethode und -stufe für jede Datei auswählen, sodass SIE compress_type und compresslevel in der Methode write() angeben.
Fügen Sie einer vorhandenen ZIP-Datei weitere Dateien hinzu
Um weitere Dateien zu einer bestehenden ZIP-Datei hinzuzufügen, setzen Sie mit zipfile.ZipFile() die erste Parameterdatei auf den Pfad der bestehenden ZIP-Datei und den zweiten Parametermodus auf ‚a‘ (append).
Vorhandene Dateien hinzufügen
Sie können vorhandene Dateien mit der write()-Methode des ZipFile-Objekts hinzufügen.
Im Folgenden sehen Sie ein Beispiel für das Hinzufügen einer other_file.txt im aktuellen Verzeichnis. Das Argument Bogenname wird weggelassen.
with zipfile.ZipFile('archive_zipfile.zip', 'a') as zf:
zf.write('another_file.txt')
Erstellen Sie eine neue Datei und fügen Sie sie hinzu
Sie können auch eine neue Datei erstellen und hinzufügen. Verwenden Sie die open()-Methode des ZipFile-Objekts mit Anhängemodus (‚a‘).
Geben Sie als ersten Parameter den Pfad der neu erstellten Datei in ZIP an und setzen Sie den zweiten Parametermodus auf ‚w‘.
Sie können den Inhalt mit der Methode write() des geöffneten Dateiobjektes schreiben.
with zipfile.ZipFile('archive_zipfile.zip', 'a') as zf:
with zf.open('dir_sub/new_file.txt', 'w') as f:
f.write(b'text in new file')
Das Argument von write() sollte als bytes angegeben werden, nicht als str. Um einen Text zu schreiben, verwenden Sie b’…‘ oder konvertieren Sie ihn mit der Methode encode() von str.
print(type(b'text'))
# <class 'bytes'>
print(type('text'.encode('utf-8')))
# <class 'bytes'>
Ein Beispiel für das Lesen einer Datei in ZIP mit open() des ZipFile-Objekts wird später beschrieben.
Überprüfen Sie die Liste der Dateien in einer ZIP-Datei
Um den Inhalt einer vorhandenen ZIP-Datei zu überprüfen, erstellen SIE ein ZipFile-Objekt mit der ersten Parameterdatei als Pfad der vorhandenen ZIP-Datei und dem zweiten Parametermodus als „r“ (lesen). Modus kann weggelassen werden, da der Standardwert ‚r‘ ist.
Sie können eine Liste der archivierten Elemente mit der namelist()-Methode des ZipFile-Objekts abrufen.
with zipfile.ZipFile('archive_zipfile.zip') as zf:
print(zf.namelist())
# ['file.txt', 'dir_sub/file_sub.txt', 'another_file.txt', 'dir_sub/new_file.txt']
with zipfile.ZipFile('archive_shutil.zip') as zf:
print(zf.namelist())
# ['dir_sub/', 'file.txt', 'dir_sub/file_sub.txt']
Wie Sie dem vorstehenden Ergebnis entnehmen können, hören Sie auch mit shutdown.make_archive() erstellte ZIPs Verzeichnisse einzeln auf. Dasselbe galt für ZIPs, die mit der Standardfunktion von Finder auf dem Mac komprimiert wurden.
Sie können Verzeichnisse mit List Comprehensions ausschließen.
with zipfile.ZipFile('archive_shutil.zip') as zf:
print([x for x in zf.namelist() if not x.endswith('/')])
# ['file.txt', 'dir_sub/file_sub.txt']
Um eine ZIP-Datei zu entpacken, erstellen Sie ein ZipFile-Objekt im Lesemodus (‚r‘, Standard).
Wenn Sie nur bestimmte Dateien extrahieren möchten, verwenden Sie die Methode extract().
Das erste Parametermitglied ist der Name der zu extrahierenden Datei (einschließlich des Verzeichnisses in der ZIP-Datei), und der zweite Parameterpfad ist der Pfad zu dem Verzeichnis, in das extrahiert werden soll.
with zipfile.ZipFile('archive_zipfile.zip') as zf:
zf.extract('file.txt', 'dir_out_extract')
zf.extract('dir_sub/file_sub.txt', 'dir_out_extract')
Wenn Sie alle Dateien extrahieren möchten, verwenden Sie die Methode extractall(). Geben Sie als erstes Argument path den Pfad des Verzeichnisses an, in das extrahiert werden soll.
with zipfile.ZipFile('archive_zipfile.zip') as zf:
zf.extractall('dir_out_extractall')
If der Pfad weggelassen WIRD, Werden die Dateien in beiden Fällen in das aktuelle Verzeichnis gespeichert. Obwohl die Dokumentation dies nicht angibt, scheint es ein neues Verzeichnis zu erstellen, selbst wenn der Pfad nicht vorhanden ist (bestätigt in Python 3.9.9).
Lesen Sie Dateien in einer ZIP-Datei
Sie können Dateien in einer ZIP-Datei direkt lesen.
Erstellen Sie ein ZipFile-Objekt im Lesemodus (Standard) und öffnen Sie die darin enthaltene Datei mit der Methode open().
Das erste Argument von open() ist der Name einer Datei im ZIP (es kann das Verzeichnis enthalten). Der zweite Argumentmodus kann weggelassen werden, da der Standardwert ‚r‘ (lesen) ist.
Der Inhalt kann mit der read()-Methode des geöffneten Dateiobjektes gelesen werden. Zurückgegeben wird ein Byte-String bytes, der mit der Methode decode() in einen String str umgewandelt werden kann.
with zipfile.ZipFile('archive_zipfile.zip') as zf:
with zf.open('dir_sub/new_file.txt') as f:
b = f.read()
print(b)
# b'text in new file'
print(type(b))
# <class 'bytes'>
s = b.decode('utf-8')
print(s)
# text in new file
print(type(s))
# <class 'str'>
Neben read() can auch readline() und readlines() sowie das mit der eingebauten Funktion open() geöffnete Dateiobjekt verwendet werden.
ZIP mit Passwörtern (Verschlüsselung und Entschlüsselung)
Das Zipfile-Modul kann ZIPs mit Passwörtern entschlüsseln (verschlüsselte ZIPs), aber keine ZIPs verschlüsseln.
Es unterstützt die Entschlüsselung verschlüsselter Dateien in ZIP-Archiven, kann jedoch derzeit keine verschlüsselte Datei erstellen. Die Entschlüsselung ist extrem langsam, da sie in nativem Python und nicht in C implementiert ist.
zipfile — Arbeiten mit ZIP-Archiven — Dokumentation zu Python 3.10.2
Außerdem wird AES nicht unterstützt.
Das Zipfile-Modul aus der Python-Standardbibliothek unterstützt nur CRC32-verschlüsselte Zip-Dateien (siehe hier: http://hg.python.org/cpython/file/71adf21421d9/Lib/zipfile.py#l420 ).
zip – Python entpackt AES-128-verschlüsselte Datei
Weder make_archive() noch unpack_archive() unterstützen Verschlüsselung und Entschlüsselung.
pyzipper
Der oben in Stack Overflow eingeführte Pyzipper unterstützt die AES-Verschlüsselung und -Entschlüsselung und kann auf die gleiche Weise wie eine Zip-Datei verwendet werden.
Um eine ZIP-Datei mit Passwort zu erstellen, spezifizieren Sie encoding=pyzipper.WZ_AES mit pyzipper.AESZipFile() und setzen Sie das Passwort mit der Methode setpassword(). Beachten Sie, dass SIE das Passwort mit der Bytefolge bytes angeben müssen.
import pyzipper
with pyzipper.AESZipFile('archive_with_pass.zip', 'w',
encryption=pyzipper.WZ_AES) as zf:
zf.setpassword(b'password')
zf.write('dir_zip/file.txt', arcname='file.txt')
zf.write('dir_zip/dir_sub/file_sub.txt', arcname='dir_sub/file_sub.txt')
Das Folgende ist ein Beispiel für das Entpacken einer ZIP-Datei mit einem Passwort.
with pyzipper.AESZipFile('archive_with_pass.zip') as zf:
zf.setpassword(b'password')
zf.extractall('dir_out_pyzipper')
Wenn das Passwort falsch ist, kann es natürlich nicht entschlüsselt werden.
# with pyzipper.AESZipFile('archive_with_pass.zip') as zf:
# zf.setpassword(b'wrong_password')
# zf.extractall('dir_out_pass')
# RuntimeError: Bad password for file 'file.txt'
Das Zipfile-Modul erlaubt Ihnen auch, ein Passwort anzugeben, aber wie oben erwähnt, unterstützt es kein AES.
# with zipfile.ZipFile('archive_with_pass.zip') as zf:
# zf.setpassword(b'password')
# zf.extractall('dir_out_pass')
# NotImplementedError: That compression method is not supported
Befehl mit subprocess.run() ausführen
Sie können auch subprocess.run() verwenden, wenn zipfile oder pyzipper nicht funktionieren, der Befehl aber trotzdem damit umgehen kann.
Verwenden Sie als Beispiel den 7z-Befehl von 7-zip (Installation erforderlich).
import subprocess
subprocess.run(['7z', 'x', 'archive_with_pass.zip', '-ppassword', '-odir_out_7z'])
Entspricht den following Befehlen. -x ist Erweiterung. Beachten Sie, dass -p und -o keine Leerzeichen benötigen.
$ 7z x archive_with_pass.zip -ppassword -odir_out_pass_7z'