Arbeiten mit ZIP/Archiven in Kotlin
In der modernen Entwicklung mit Kotlin (sowohl für JVM als auch für Android) besteht häufig die Notwendigkeit, Dateien in ZIP-Archive zu packen oder Daten daraus zu extrahieren. Die Standardbibliothek von Java (java.util.zip) bietet alle notwendigen Klassen, die auch in Kotlin hervorragend funktionieren. In diesem Artikel werden wir die drei grundlegenden Operationen im Detail besprechen: Erstellen eines Archivs, Lesen des Inhalts und Entpacken von Dateien.
1. Erstellen eines ZIP-Archivs (Dateien packen)
Zum Erstellen eines Archivs wird ZipOutputStream verwendet. Jede Datei wird als separater Eintrag (ZipEntry) hinzugefügt. Betrachten wir ein Beispiel, das mehrere Dateien in ein Archiv packt.
import java.io.Fileimport java.io.FileInputStreamimport java.io.FileOutputStreamimport java.util.zip.ZipEntryimport java.util.zip.ZipOutputStream
fun createZip( filesToZip: List<File>, outputZipFile: File) { ZipOutputStream(FileOutputStream(outputZipFile)).use { zipOut -> for (file in filesToZip) { // Erstelle einen Eintrag mit dem Dateinamen val entry = ZipEntry(file.name) zipOut.putNextEntry(entry)
// Lese die Quelldatei und schreibe sie ins Archiv FileInputStream(file).use { fis -> fis.copyTo(zipOut) } zipOut.closeEntry() } }}
fun main() { val files = listOf( File("document.txt"), File("image.png"), File("data.json") ) val archive = File("my_archive.zip") createZip(files, archive) println("Archiv erstellt: ${archive.absolutePath}")}Beachten Sie die Verwendung von .use { ... } – dies ist ein sicheres Schließen von Ressourcen, äquivalent zu try-with-resources in Java. Wenn Dateien aus Unterverzeichnissen gepackt werden sollen, müssen die Verzeichnisse rekursiv durchlaufen und die relativen Pfade im Namen des ZipEntry gespeichert werden.
2. Lesen des Archivinhalts (Dateiliste anzeigen)
Manchmal ist es erforderlich, nur die Dateien innerhalb eines Archivs anzusehen, ohne sie zu extrahieren. Dazu wird ZipFile oder ZipInputStream verwendet. Die erste Variante ist praktischer, wenn das Archiv bereits existiert und nicht zu groß ist.
import java.io.Fileimport java.util.zip.ZipFile
fun listZipContent(zipFile: File) { ZipFile(zipFile).use { zip -> val entries = zip.entries() while (entries.hasMoreElements()) { val entry = entries.nextElement() println("${entry.name} (${entry.size} Bytes)") } }}
fun main() { val archive = File("my_archive.zip") if (archive.exists()) { listZipContent(archive) } else { println("Datei nicht gefunden") }}Die Methode entries() gibt eine Aufzählung aller Einträge zurück. Für jeden Eintrag sind Name, Größe, Änderungsdatum und Flags (z. B. ob der Eintrag ein Verzeichnis ist) verfügbar.
3. Entpacken eines ZIP-Archivs (Dateien extrahieren)
Zum Extrahieren von Dateien ist die Verwendung von ZipInputStream praktisch. Es liest das Archiv sequenziell, Eintrag für Eintrag. Nachfolgend finden Sie ein Beispiel für das vollständige Entpacken in einen angegebenen Ordner.
import java.io.Fileimport java.io.FileInputStreamimport java.io.FileOutputStreamimport java.util.zip.ZipInputStream
fun extractZip( zipFile: File, outputDir: File) { if (!outputDir.exists()) { outputDir.mkdirs() }
ZipInputStream(FileInputStream(zipFile)).use { zis -> var entry = zis.nextEntry while (entry != null) { val targetFile = File(outputDir, entry.name)
// Erstelle übergeordnete Verzeichnisse, falls nötig targetFile.parentFile?.mkdirs()
// Wenn der Eintrag ein Verzeichnis ist, erstelle es einfach if (entry.isDirectory) { targetFile.mkdirs() } else { Auch in der Bibliothek
SMS-Versand mit PHP: API-Bibliotheken für die Integration
ORM für Rust: Vergleich und Beispiele mit Diesel, SeaORM und SQLx
unbuild für TypeScript: Komplettguide mit Beispielen
Caching in TypeScript: Redis, Memcached und In-Memory-Lösungen
OpenAPI / Swagger für Java: Vollständige Anleitung mit Beispielen