Holger Stehle

Softwareentwicklung und -architektur

« ZIP-Archive (ent-)packen

ZIP-Archive sind praktisch, um Dateien und Verzeichnisstrukturen komprimiert und zusammenhängend speichern und austauschen zu können und werden außerdem auf praktisch jeder Plattform unterstützt. Daher möchte ich mit diesem Beitrag zeigen, wie sich mit C# entsprechende Archive automatisch erstellen lassen.

Das .NET-Framework liefert im Namensraum System.IO.Compression grundlegende Funktionalität zur Arbeit mit entsprechenden Archiven, auf die wir in diesem Beitrag setzen werden.

Zuerst möchte ich ein paar Möglichkeiten aufzeigen, um ZIP-Archive zu erstellen:

// Archiv aus bestehendem Verzeichnis erstellen
ZipFile.CreateFromDirectory("data", "data.zip");

// Archiv aus bestehenden Dateien erstellen
using(FileStream fileStream = File.OpenWrite("data.zip")) {
    using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create)) {
        zipArchive.CreateEntryFromFile("data/a.txt", "a.txt");
        zipArchive.CreateEntryFromFile("data/b.txt", "b.txt");
    }
}

// Archiv manuell zusammenstellen
using(FileStream fileStream = File.OpenWrite("data.zip")) {
    using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create)) {
        ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry("README");

        using(StreamWriter streamWriter = new StreamWriter(zipArchiveEntry.Open())) {
            streamWriter.Write("Hallo Welt!");
        }
    }
}

Abschließend möchten wir auf bestehende Archive zugreifen:

// Archiv vollständig entpacken
ZipFile.ExtractToDirectory("data.zip", "data");

// Archiv einlesen und verarbeiten
using(FileStream fileStream = File.OpenRead("data.zip")) {
    using(ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read)) {
        foreach(ZipArchiveEntry zipArchiveEntry in zipArchive.Entries) {
              // "README" separat berücksichtigen
            if(zipArchiveEntry.Name == "README") {
                using(StreamReader streamReader = new StreamReader(zipArchiveEntry.Open())) {
                      // Inhalt einlesen und auf Konsole ausgeben
                    Console.WriteLine(streamReader.ReadToEnd());
                }
            } else {
                  // Eintrag als Datei speichern
                zipArchiveEntry.ExtractToFile(zipArchiveEntry.Name);
            }
        }
    }
}

Durch die Verwendung von Datenströmen besteht grundsätzlich die Möglichkeit, nahezu beliebige Quellen (und Ziele) für Archiv-Einträge heranzuziehen.