Kurs
Voraussetzungen für die Arbeit mit ZIP-Dateien
- Du solltest die Dateiverarbeitung in Python kennen, um den Umgang mit ZIP-Dateien zu verstehen. Falls nicht, schau dir bei W3Schools den Abschnitt File Handling an.
- OOP-Grundkonzepte in Python
- Python-Grundlagen wie Bedingungen, Schleifen, Funktionen, Klassen usw.
- Wenn du Python noch nicht kennst, mach den kostenlosen DataCamp-Kurs Intro to Python for Data Science oder lies die offizielle Dokumentation von Python.
Öffne diesen Link, um alle ZIP-Ordner herunterzuladen, die ich in den nächsten Abschnitten verwende.
Was ist eine ZIP-Datei?
ZIP ist ein Archivdateiformat mit verlustfreier Datenkompression. Die ZIP-Datei ist eine einzelne Datei, die eine oder mehrere komprimierte Dateien enthält.
Wofür nutzt man ZIP-Dateien?
- ZIP-Dateien helfen dir, zusammengehörige Dateien an einem Ort zu bündeln.
- ZIP-Dateien reduzieren die Dateigröße.
- ZIP-Dateien lassen sich über viele Verbindungen schneller übertragen als einzelne Dateien.
zipfile-Modul
Verschaffe dir mit der Methode dir() einen Überblick über alle Methoden und Klassen des zipfile-Moduls. Schau dir den Code an, um alle Klassen und Methoden des zipfile-Moduls zu erhalten.
import zipfile # importing the 'zipfile' module
print(dir(zipfile))
['BZIP2_VERSION', 'BadZipFile', 'BadZipfile', 'DEFAULT_VERSION', 'LZMACompressor', 'LZMADecompressor', 'LZMA_VERSION', 'LargeZipFile', 'MAX_EXTRACT_VERSION', 'PyZipFile', 'ZIP64_LIMIT', 'ZIP64_VERSION', 'ZIP_BZIP2', 'ZIP_DEFLATED', 'ZIP_FILECOUNT_LIMIT', 'ZIP_LZMA', 'ZIP_MAX_COMMENT', 'ZIP_STORED', 'ZipExtFile', 'ZipFile', 'ZipInfo', '_CD64_CREATE_VERSION', '_CD64_DIRECTORY_RECSIZE', '_CD64_DIRECTORY_SIZE', '_CD64_DISK_NUMBER', '_CD64_DISK_NUMBER_START', '_CD64_EXTRACT_VERSION', '_CD64_NUMBER_ENTRIES_THIS_DISK', '_CD64_NUMBER_ENTRIES_TOTAL', '_CD64_OFFSET_START_CENTDIR', '_CD64_SIGNATURE', '_CD_COMMENT_LENGTH', '_CD_COMPRESSED_SIZE', '_CD_COMPRESS_TYPE', '_CD_CRC', '_CD_CREATE_SYSTEM', '_CD_CREATE_VERSION', '_CD_DATE', '_CD_DISK_NUMBER_START', '_CD_EXTERNAL_FILE_ATTRIBUTES', '_CD_EXTRACT_SYSTEM', '_CD_EXTRACT_VERSION', '_CD_EXTRA_FIELD_LENGTH', '_CD_FILENAME_LENGTH', '_CD_FLAG_BITS', '_CD_INTERNAL_FILE_ATTRIBUTES', '_CD_LOCAL_HEADER_OFFSET', '_CD_SIGNATURE', '_CD_TIME', '_CD_UNCOMPRESSED_SIZE', '_ECD_COMMENT', '_ECD_COMMENT_SIZE', '_ECD_DISK_NUMBER', '_ECD_DISK_START', '_ECD_ENTRIES_THIS_DISK', '_ECD_ENTRIES_TOTAL', '_ECD_LOCATION', '_ECD_OFFSET', '_ECD_SIGNATURE', '_ECD_SIZE', '_EndRecData', '_EndRecData64', '_FH_COMPRESSED_SIZE', '_FH_COMPRESSION_METHOD', '_FH_CRC', '_FH_EXTRACT_SYSTEM', '_FH_EXTRACT_VERSION', '_FH_EXTRA_FIELD_LENGTH', '_FH_FILENAME_LENGTH', '_FH_GENERAL_PURPOSE_FLAG_BITS', '_FH_LAST_MOD_DATE', '_FH_LAST_MOD_TIME', '_FH_SIGNATURE', '_FH_UNCOMPRESSED_SIZE', '_SharedFile', '_Tellable', '_ZipDecrypter', '_ZipWriteFile', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_compression', '_check_zipfile', '_get_compressor', '_get_decompressor', 'binascii', 'bz2', 'compressor_names', 'crc32', 'error', 'importlib', 'io', 'is_zipfile', 'lzma', 'main', 'os', 're', 'shutil', 'sizeCentralDir', 'sizeEndCentDir', 'sizeEndCentDir64', 'sizeEndCentDir64Locator', 'sizeFileHeader', 'stat', 'stringCentralDir', 'stringEndArchive', 'stringEndArchive64', 'stringEndArchive64Locator', 'stringFileHeader', 'struct', 'structCentralDir', 'structEndArchive', 'structEndArchive64', 'structEndArchive64Locator', 'structFileHeader', 'sys', 'threading', 'time', 'zlib']
Du hast eine Menge Klassen und Methoden gesehen, richtig. Aber du musst nicht alle lernen. Du lernst nur die wichtigsten Klassen und Methoden, um mit ZIP-Dateien zu arbeiten.
Schauen wir uns die nützlichsten Exceptions, Klassen und Methoden mit kurzen Erklärungen an.
Exceptions
Eine Exception ist eine Meldung, mit der du Fehler gezielt abfangen und ausgeben kannst. In Python nutzt du die Schlüsselwörter try, except, finally für das Fehlerhandling.
Wenn du beim Fehlerhandling noch unsicher bist, lies in der Fehlerbehandlung der Python-Dokumentation nach.
Schauen wir uns die Exceptions im zipfile-Modul an.
zipfile.BadZipFile
zipfile.BadZipFile ist eine Exception im zipfile-Modul. Sie wird bei defekten ZIP-Dateien ausgelöst. Sieh dir das Beispiel an.
## zipfile.BadZipFile
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file: # opening the zip file using 'zipfile.ZipFile' class
print("Ok")
except zipfile.BadZipFile: # if the zip file has any errors then it prints the error message which you wrote under the 'except' block
print('Error: Zip file is corrupted')
if __name__ == '__main__': main()
## I used a badfile for the test
Ok
zipfile.LargeZipFile
Wenn du mit einer sehr großen ZIP-Datei arbeitest, musst du die ZIP64-Funktionalität beim Öffnen aktivieren. Andernfalls wird LargeZipFile ausgelöst. Hier ein Beispiel.
## zipfile.LargeZipFile
## Without enabling 'Zip64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file:
print('File size is compatible')
except zipfile.LargeZipFile: # it raises an 'LargeZipFile' error because you didn't enable the 'Zip64'
print('Error: File size if too large')
if __name__ == '__main__': main()
File size is compatible
## zipfile.LargeZipFile
## With enabling 'ZIP64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip', mode = 'r', allowZip64 = True) as file: # here enabling the 'Zip64'
print('File size is compatible')
except zipfile.LargeZipFile:
print('Error: File size if too large') # if the file size is too large to open it prints the error you have written
if __name__ == '__main__': main()
File size is compatible
Wähle eine ZIP-Datei, die sich für das Exception-Handling eignet, und führe das Programm aus. So wird das Verhalten klarer.
Klassen
Vereinfacht gesagt ist eine Klasse eine Sammlung von Methoden und Attributen. Du nutzt sie, indem du Instanzen dieser Klasse erstellst.
Schauen wir uns einige Klassen des zipfile-Moduls an.
zipfile.ZipFile
Die am häufigsten genutzte Klasse für die Arbeit mit ZIP-Dateien ist ZipFile.
zipfile.ZipFile dient zum Schreiben und Lesen von ZIP-Dateien. Die Klasse bietet verschiedene Methoden zur Arbeit mit ZIP-Dateien.
Erkunde jetzt die Methoden der Klasse ZipFile mit dir(). Hier der Code.
import zipfile
print(dir(zipfile.ZipFile)) # accessing the 'ZipFile' class
['_RealGetContents', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_extract_member', '_fpclose', '_open_to_write', '_sanitize_windows_name', '_windows_illegal_name_trans_table', '_write_end_record', '_writecheck', 'close', 'comment', 'extract', 'extractall', 'fp', 'getinfo', 'infolist', 'namelist', 'open', 'printdir', 'read', 'setpassword', 'testzip', 'write', 'writestr']
Die Klasse zipfile.ZipFile hast du in früheren Beispielen bereits zum Lesen von ZIP-Dateien verwendet.
zipfile.ZipFile bietet viele Methoden wie extract, open, getinfo, setpassword usw., um mit ZIP-Dateien zu arbeiten.
Schauen wir uns einige Methoden der Klasse ZipFile an.
## zipfile.ZipFile
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# ZipFile.infolist() returns a list containing all the members of an archive file
print(file.infolist())
# ZipFile.namelist() returns a list containing all the members with names of an archive file
print(file.namelist())
# ZipFile.getinfo(path = filepath) returns the information about a member of Zip file.
# It raises a KeyError if it doesn't contain the mentioned file
print(file.getinfo(file.namelist()[-1]))
# ZipFile.open(path = filepath, mode = mode_type, pwd = password) opens the members of an archive file
# 'pwd' is optional -> if it has password mention otherwise leave it
text_file = file.open(name = file.namelist()[-1], mode = 'r')
# 'read()' method of the file prints all the content of the file. You see this method in file handling.
print(text_file.read())
# You must close the file if you don't open a file using 'with' keyword
# 'close()' method is used to close the file
text_file.close()
# ZipFile.extractall(path = filepath, pwd = password) extracts all the files to current directory
file.extractall()
# after executing check the directory to see extracted files
if __name__ == '__main__': main()
[<ZipInfo filename='extra_file.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='READ ME.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>]
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>
b"num = int(input('Enter a Number:- '))\r\nif num % 2 == 0:\r\n\tprint('{} is Even'.fromat(num))\r\nelse:\r\n\tprint('{} is Odd'.fromat(num))"
Wenn du alle Methoden der Klasse ZipFile kennenlernen willst, nutze help() für die jeweilige Methode.
Oder sieh dir die offizielle Dokumentation von Python an.
zipfile.ZipInfo
Die Klasse zipfile.ZipInfo repräsentiert ein Element in einem ZIP-Archiv.
Erkunde zunächst alle Attribute und Methoden der Klasse zipfile.ZipInfo mit dir(). Hier der Code.
## zipfile.ZipInfo
import zipfile
print(dir(zipfile.ZipInfo))
['CRC', 'FileHeader', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_decodeExtra', '_encodeFilenameFlags', '_raw_time', 'comment', 'compress_size', 'compress_type', 'create_system', 'create_version', 'date_time', 'external_attr', 'extra', 'extract_version', 'file_size', 'filename', 'flag_bits', 'from_file', 'header_offset', 'internal_attr', 'is_dir', 'orig_filename', 'reserved', 'volume']
Jetzt schauen wir uns einige Methoden der Klasse zipfile.ZipInfo an.
## zipfile.ZipInfo
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# 'infolist()' is the object of 'ZipFile' class
# 'infolist()' returns a list containing all the folders and files of the zip -> 'ZipInfo' objects
# assigning last element of the list to a variable to test all the methods of 'ZipInfo'
archive = file.infolist()
read_me_file = archive[-1]
# 'ZipInfo' methods
# ZipInfo_object.filename returns the name of the file
print("Name of the file:- {}".format(read_me_file.filename))
# ZipInfo_object.file_size returns the size of the file
print("Size of the file:- {}".format(read_me_file.file_size))
# ZipInfo_object.is_dir() returns True if it's directory otherwise False
print("Is directory:- {}".format(read_me_file.is_dir()))
# ZipInfo_object.date_time() returns the created date & time of file
print("File created data & time:- {}".format(read_me_file.date_time))
if __name__ == '__main__': main()
Name of the file:- sample_file/READ ME.txt
Size of the file:- 59
Is directory:- False
File created data & time:- (2018, 10, 4, 11, 32, 22)
Weitere Infos findest du unter ZipInfo in der ZipInfo-Dokumentation.
Methoden
Methoden sind Codeblöcke für eine bestimmte Funktionalität im Programm. Wenn du zum Beispiel den Absolutwert einer Zahl brauchst, nutzt du in Python die Methode abs.
Du kannst Methoden überall verwenden, wo du sie brauchst. Schauen wir uns einige Methoden des zipfile-Moduls an.
zipfile.is_zipfile()
Die Methode is_zipfile(filename) des zipfile-Moduls gibt True zurück, wenn die Datei eine gültige ZIP-Datei ist, sonst False.
Hier ein Beispiel.
## zipfile.is_zip(filename)
import zipfile
def main():
print(zipfile.is_zipfile('sample_file.zip')) # it returns True
if __name__ == '__main__': main()
True
Umgang mit ZIP-Dateien
In diesem Abschnitt lernst du, wie du ZIP-Dateien öffnest, entpackst, schreibst usw.
Eine ZIP-Datei entpacken
Entpacke die Inhalte einer ZIP-Datei mit der Methode extractall in das aktuelle Verzeichnis.
## extracting zip file
import zipfile
def main():
# assigning filename to a variable
file_name = 'sample_file.zip'
# opening Zip using 'with' keyword in read mode
with zipfile.ZipFile(file_name, 'r') as file:
# printing all the information of archive file contents using 'printdir' method
print(file.printdir())
# extracting the files using 'extracall' method
print('Extracting all files...')
file.extractall()
print('Done!') # check your directory of zip file to see the extracted files
if __name__ == '__main__': main()
File Name Modified Size
sample_file/ 2018-10-04 11:33:22 0
sample_file/even_odd.py 2018-06-29 23:35:54 129
sample_file/READ ME.txt 2018-10-04 11:32:22 59
None
Extracting all files...
Done!
Eine passwortgeschützte ZIP entpacken
Um eine ZIP mit Passwort zu entpacken, übergib den Wert an das Positionsargument pwd der Methoden extract(pwd = password) oder extractall(pwd = password).
Das Passwort muss als Bytes vorliegen. Um str in Bytes zu konvertieren, verwende die eingebaute Python-Funktion bytes mit dem Encoding utf-8.
Hier ein Beispiel.
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'datacamp'
with zipfile.ZipFile(file_name) as file:
# password you pass must be in the bytes you converted 'str' into 'bytes'
file.extractall(pwd = bytes(pswd, 'utf-8'))
if __name__ == '__main__': main()
Du kannst Dateien auch über die Methode setpassword(pwd = password) der Klasse ZipFile entpacken. Sieh dir das Beispiel an.
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'datacamp'
with zipfile.ZipFile(file_name) as file:
# 'setpassword' method is used to give a password to the 'Zip'
file.setpassword(pwd = bytes(pswd, 'utf-8'))
file.extractall()
if __name__ == '__main__': main()
ZIP-Dateien erstellen
Zum Erstellen einer ZIP-Datei brauchst du keine zusätzlichen Methoden. Übergib einfach den Namen an die Klasse ZipFile, und im aktuellen Verzeichnis wird ein Archiv erstellt.
Hier ein Beispiel.
## Creating Zip file
import zipfile
def main():
archive_name = 'example_file.zip'
# below one line of code will create a 'Zip' in the current working directory
with zipfile.ZipFile(archive_name, 'w') as file:
print("{} is created.".format(archive_name))
if __name__ == '__main__': main()
example_file.zip is created.
In ZIP-Dateien schreiben
Öffne ZIP-Archive im Schreibmodus, um Dateien hinzuzufügen. Dabei werden vorhandene Dateien im ZIP überschrieben.
Hier ein Beispiel.
## Writing files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# Opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'w') as file:
# write mode overrides all the existing files in the 'Zip.'
# you have to create the file which you have to write to the 'Zip.'
file.write('extra_file.txt')
print('File overrides the existing files')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
File overrides the existing files
['extra_file.txt']
Dateien zu ZIP hinzufügen
Öffne ZIP im Append-Modus (a), um Dateien anzuhängen. Vorhandene Dateien werden dabei nicht überschrieben.
Hier ein Beispiel.
## Appending files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'a') as file:
# append mode adds files to the 'Zip'
# you have to create the files which you have to add to the 'Zip'
file.write('READ ME.txt')
file.write('even_odd.py')
print('Files added to the Zip')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
Files added to the Zip
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
Bis hierhin hast du gelernt, wie man mit ZIP-Dateien umgeht. Du kannst jetzt öffnen, schreiben, anhängen, entpacken, erstellen usw. Als Nächstes schreibst du ein kleines Programm.
Schauen wir uns an, was es macht.
Mehrere verschachtelte ZIPs mit Passwort per Schleife und zipfile entpacken
- Du hast eine ZIP, die in der Tiefe mehrere weitere ZIP-Dateien enthält. Jede dieser ZIP-Dateien hat als Passwort ihren Dateinamen. Die Aufgabe: Entpacke alle ZIPs, bis du am Ende ankommst.
Schritte zur Lösung
- Entpacke die übergeordnete Datei mit ihrem Namen als Passwort.
- Ermittle mit namelist() den Namen des ersten Kindelements und speichere ihn in einer Variablen.
-
Starte eine Schleife für unendlich viele Durchläufe.
-
Prüfe mit is_zipfile(), ob die Datei eine ZIP ist. Wenn ja, dann:
-
Öffne die ZIP mit der Variable name.
-
Leite das Passwort der ZIP aus der Variablen name ab.
-
Entpacke die ZIP.
-
Ermittle und speichere den nächsten ZIP-Namen erneut in der Variablen name.
-
-
Sonst
- Beende die Schleife mit break.
-
Ich habe die obige Vorgehensweise erstellt. Je nach Struktur deiner Dateien kannst du sie anpassen.
## Solution
import zipfile
def main():
# storing the parent name
parent_file_name = '000.zip'
with zipfile.ZipFile(parent_file_name, 'r') as parent_file:
# extracting the parent file
pswd = bytes(parent_file_name.split('.')[0], 'utf-8')
parent_file.extractall(pwd = pswd)
# getting the first child
next_zip_name = parent_file.namelist()[0]
# looping through the sub zips infinite times until you don't encouter a 'Zip' file
while True:
if zipfile.is_zipfile(next_zip_name):
# opening the zip
with zipfile.ZipFile(next_zip_name, 'r') as child_file:
# getting password from the zip name
pswd = bytes(next_zip_name.split('.')[0], 'utf-8')
# extracting the zip
child_file.extractall(pwd = pswd)
# getting the child zip name
next_zip_name = child_file.namelist()[0]
else:
break
if __name__ == '__main__': main()
Nach dem Ausführen des Programms siehst du alle Unter-ZIPs im aktuellen Verzeichnis entpackt.
Schlusswort
Glückwunsch, du hast das Tutorial abgeschlossen!
Ich hoffe, es hat dir gefallen. Dieser Artikel hilft dir enorm, wenn du mit ZIP-Dateien arbeitest. Jetzt kannst du sicher mit ZIP-Dateien umgehen.
Wenn du Fragen zum Artikel hast, stell sie gern in den Kommentaren. Ich antworte so schnell wie möglich.
Wenn du neu bei Python bist, mach den kostenlosen DataCamp-Kurs Intro to Python for Data Science oder lies die offizielle Dokumentation von Python.
Viel Spaß beim Coden!