Frage

habe ich den folgenden Code-Dateien zu komprimieren und sie weiter wachsen statt schrumpfen. Ich comressed eine 4 kb-Datei und es wurde 6., dass wegen der Kompression Overhead für eine kleine Datei verständlich ist. Ich habe versucht, eine 400 MB-Datei, und es wurde 628 mb nach Komprimierung. Was ist falsch? Siehe den Code. (.Net 2.0)

Public Sub Compress(ByVal infile As String, ByVal outfile As String)
    Dim sourceFile As FileStream = File.OpenRead(inFile)
    Dim destFile As FileStream = File.Create(outfile)

    Dim compStream As New GZipStream(destFile, CompressionMode.Compress)

    Dim myByte As Integer = sourceFile.ReadByte()
    While myByte <> -1
        compStream.WriteByte(CType(myByte, Byte))
        myByte = sourceFile.ReadByte()
    End While

    sourceFile.Close()
    destFile.Close()
End Sub
War es hilfreich?

Lösung

Sind Sie sicher, dass das Schreiben Byte für Byte in den Stream eine wirklich gute Idee ist? Es wird sicherlich nicht ideal Leistungseigenschaften haben und vielleicht ist es das, was auch die gzip komprimiert Algorithmus verwechselt.

Auch könnte es vorkommen, dass die Daten, die Sie komprimieren möchten, ist einfach nicht wirklich gut komprimierbar. Wenn ich Sie wäre, würde ich Ihren Code mit einem Textdokument mit der gleichen Größe versuchen wie Textdokumente viel besser zu komprimieren neigen als binären Zufalls.

Auch könnte man versuchen, eine reine DeflateStream Verwendung als zu einem GZipStream Gegensatz, da sie beide den gleichen Kompressionsalgorithmus verwenden (abzulassen), der einzige Unterschied ist, dass gzip einige zusätzliche Daten ergänzt (wie Fehlerprüfung) so ein DeflateStream könnte kleiner Ausbeute Ergebnisse.

Meine VB.NET ist ein bisschen rostig, so werde ich lieber nicht versuchen, ein Codebeispiel in VB.NET zu schreiben. Stattdessen ist hier, wie Sie es in C # tun sollen, sollte es relativ einfach sein, es für jemanden mit einem wenig Erfahrung zu VB.NET zu übersetzen (oder vielleicht jemand, der in VB.NET gut könnte meinen Beitrag bearbeiten und übersetzt es VB.NET)

FileStream sourceFile;
GZipStream compStream;

byte[] buffer = new byte[65536];
int bytesRead = 0;
while (bytesRead = sourceFile.Read(buffer, 0, 65536) > 0)
{
     compStream.Write(buffer, 0, bytesRead);
}

Andere Tipps

Wenn die zugrunde liegende Datei selbst ist sehr unberechenbar (bereits komprimierte oder weitgehend zufällig) dann zu komprimieren versucht, es wird die Datei verursacht größer werden.

von 400 bis 628Mb gehen klingt höchst unwahrscheinlich als Expansionsfaktor, da der deflate-Algorithmus (für GZIP) tendiert in Richtung einer maximaler Expansionsfaktor von 0,03% der Overhead der GZIP-Header sollte vernachlässigbar sein.

Edit: Die 4.0 c # Veröffentlichung zeigt, dass die Kompression Bibliotheken verbessert wurden deutliche Ausweitung der komprimierbare Daten zu verursachen. Dies deutet darauf hin, dass sie den „Rückfall auf den rohen Strom blockiert“ Modus nicht implementiert. Versuchen Sie SharpZipLib Bibliothek als Schnelltest. Das sollte man mit nahezu identischer Leistung bereitzustellen, wenn der Strom durch deflate nicht komprimierbar ist. Wenn es nicht die Auffassung für eine leistungsfähigere BCL Implementierung auf diesem oder warten auf die Version 4.0 zu bewegen. Beachten Sie, dass der Mangel an Kompression Sie stark immer legt nahe, dass es keinen Punkt, den Sie versuchen, weiter zu komprimieren sowieso

Dies ist ein bekannt rel="nofollow Anomalie mit dem eingebauten in GZipStream (Und DeflateStream).
Ich kann mich zwei Lösungen:

  • einen alternativen Kompressor verwenden.
  • bauen einige Logik, die die Größe des „komprimiert“ Ausgang und vergleicht sie mit der Größe der Eingabe überprüft. Wenn größer, chuck die Ausgabe und nur die Daten speichern.

DotNetZip enthält einen "festen" GZipStream basierend auf einem verwalteten Hafen von zlib. (Es dauert Ansatz # 1 von oben). Die Ionic.Zlib.GZipStream kann das eingebaute in GZipStream in Ihren Anwendungen mit einem einfachen Namensraum Swap ersetzen.

Vielen Dank für gute Antworten. Früher habe ich versucht, .wmv-Dateien und eine Textdatei zu komprimieren. Ich änderte den Code zu DeflateStream und es scheint jetzt zu funktionieren. Prost.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top