Feedback

C# - Datei mi GZip packen

Veröffentlicht von am 21.10.2010
(0 Bewertungen)
Mit diesem Snippet, könnt ihr Dateien einfach und schnell via GZip packen.

by: coding-community.com
/// <summary>
/// Erstellt eine gepackte Datei, welche den Dateinamen enthält, jededoch mit .gz endet.
/// </summary>
/// <param name="Pfad">Pfad zur Datei, welche gepackt werden soll.</param>
static void GZipFile(string Pfad)
{
 Byte[] datei = File.ReadAllBytes(Pfad);
 GZipStream gzipStream = new GZipStream(new FileStream(Pfad + ".gz", System.IO.FileMode.Create), CompressionMode.Compress);
 foreach (Byte byt in datei)
 {
  gzipStream.WriteByte(byt);
 }
 gzipStream.Close();
}
Abgelegt unter gzip, compress, packen, datei.

4 Kommentare zum Snippet

SKull schrieb am 25.10.2010:
using System.IO;
using System.IO.Compression;
Martin Dauskardt schrieb am 24.11.2010:
Und wo wir schon mal bei den usings sind,
nutzen wir sie auch gleich. :-)

            
using (new GZipStream(new FileStream(SourceFile + ".gz", System.IO.FileMode.Create), CompressionMode.Compress))
{
foreach (Byte byt in datei)
{
gzipStream.WriteByte(byt);
}
}
Martin Dauskardt schrieb am 24.11.2010:
Besser so..

using (GZipStream gzipStream = new GZipStream(new FileStream(SourceFile + ".gz", System.IO.FileMode.Create), CompressionMode.Compress))
{
foreach (Byte byt in datei)
{
gzipStream.WriteByte(byt);
}
}
AI schrieb am 19.01.2026:
Aus 2010 kennt man solche Beispiele: „Datei lesen, GZipStream aufmachen, Byte für Byte reinschieben“. Funktional ist das, aber die Umsetzung ist heute unnötig langsam und speicherhungrig, weil die komplette Datei in den RAM geladen wird und anschließend Byte-weise geschrieben wird.

Analyse nach heutigen Kriterien:
- Performance: File.ReadAllBytes lädt die gesamte Datei in den Speicher. Für große Dateien ist das unnötig und kann zu starkem Memory-Pressure führen. Das Byte-für-Byte-Schreiben über WriteByte ist extrem ineffizient, weil pro Byte ein Methodenaufruf erfolgt.
- Memory-Allokationen: Der komplette Dateipuffer wird auf einmal allokiert. Für „packen“ ist Streaming der Standard: lesen in Blöcken und direkt komprimiert wegschreiben.
- Robustheit: Der Stream wird per Close geschlossen, aber nicht deterministisch bei Exceptions freigegeben. using/using var ist Pflicht, damit FileHandles sicher geschlossen werden.
- Korrektheit: Der FileStream wird ohne using erstellt und lebt ausschließlich „unter“ dem GZipStream. Das ist ok, aber dann muss Dispose garantiert passieren. Außerdem ist FileMode.Create ok, überschreibt aber stillschweigend bestehende .gz-Dateien.
- Cloud/Container: Datei-I/O ist grundsätzlich ok, aber in Container/Cloud-Workloads möchte man häufig Stream-basierte APIs, um auch mit Netzwerk- oder Object-Storage-Streams arbeiten zu können.
- Thread-Safety: Die Methode ist thread-safe, solange jeder Aufruf auf eigene Pfade/Streams arbeitet. Gleichzeitiges Packen derselben Zieldatei ist ein fachlicher Konflikt.

Modernisierte Variante (streaming, schnelle Pfade, sauberes Dispose):

using System;
using System.IO;
using System.IO.Compression;

public static class GZipPacker
{
public static void GZipFile(string path, CompressionLevel level = CompressionLevel.Optimal)
{
if (path is null) throw new ArgumentNullException(nameof(path));

string gzPath = path + ".gz";

using var input = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024 * 128, useAsync: false);
using var output = new FileStream(gzPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1024 * 128, useAsync: false);
using var gzip = new GZipStream(output, level, leaveOpen: false);

input.CopyTo(gzip);
}
}


Warum das heute objektiv besser ist:
- Performance: CopyTo nutzt gepufferte Blockkopie statt WriteByte pro Byte.
- Memory-Allokationen: Kein vollständiges Einlesen der Datei in ein Byte-Array, dadurch deutlich weniger RAM-Spitzen.
- Robustheit: using/using var garantiert das Schließen aller Handles auch bei Exceptions.
- Wartbarkeit: CompressionLevel ist explizit und die Methode ist klarer in Verantwortung und Verhalten.
 

Logge dich ein, um hier zu kommentieren!