Datenkomprimierung mit GZip Streams

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Killerjo96.

    Datenkomprimierung mit GZip Streams

    Hallöschen,

    da bin ich auch schon wieder beim nächsten Problem...

    Folgenden Code habe ich im Internet gesucht und gefunden, und "durchstudiert"...naja so halbwegs.

    VB.NET-Quellcode

    1. Public Function UnzipFile(ByVal sZipFile As String) As Boolean
    2. Try
    3. ' Existiert die Datei überhaupt
    4. If System.IO.File.Exists(sZipFile) Then
    5. ' GZIP-Datei öffnen
    6. Dim oStream As New System.IO.FileStream(sZipFile, IO.FileMode.Open)
    7. Dim oCompress As New System.IO.Compression.GZipStream(oStream, IO.Compression.CompressionMode.Decompress)
    8. 'ORIGINAL TEIL
    9. '' Inhalt blockweise auslesen und dekomprimieren
    10. 'Dim bBuffer() As Byte
    11. 'Dim nOffset As Integer = 0
    12. 'Dim nCount As Integer = 0
    13. 'While True
    14. ' ReDim Preserve bBuffer(nCount + 100)
    15. ' Dim nBytes As Integer = oCompress.Read(bBuffer, nOffset, 100)
    16. ' If nBytes = 0 Then Exit While
    17. ' nOffset += nBytes
    18. ' nCount += nBytes
    19. 'End While
    20. 'ReDim Preserve bBuffer(nCount - 1)
    21. 'ORIGINAL TEIL
    22. ' MEIN VERSUCHSTEIL
    23. Dim bBuffer(oStream.Length) As Byte
    24. With oCompress
    25. .Read(bBuffer, 0, bBuffer.Length)
    26. .Close()
    27. End With
    28. ' MEIN VERSUCHSTEIL
    29. ' Byte-Array in Zieldatei speichern
    30. My.Computer.FileSystem.WriteAllBytes(sZipFile.Substring(0, sZipFile.Length - 3), bBuffer, False)
    31. oStream.Close()
    32. oCompress.Close()
    33. Return True
    34. End If
    35. Catch
    36. Return False
    37. End Try
    38. End Function


    Der auskommentierte Code ist der original code und der der jetzt drin steht (Der eig. das selbe machen sollte wie der auskommentierte) ist von mir, er tut nur leider nich dasselbe... Ziel ist es, eine .gz datei zu dekomprimieren... ansich funktioniert es mit dem original code aber dort dauert der vorgang vom dekomprimieren total lange.. selbst wenn ich die bytes vergrößere ... deswegen hab ich mir das original code stück genauer angesehen, im prinzip wird doch nur die .gz datei ausgelesen und dekomprimiert... nunja ich möchte jetzt nicht immer blockweise die datei zusammenstellen sondern am stück, weiß einer wie ich des realisieren könnte? ich weiß nämlich nicht mehr weiter und so viel erfahrung mit dekomprimierung und streams habe ich auch (noch) nicht.

    danke im voraus :rolleyes:

    AliveDevil schrieb:

    guck dir mal das [VB.NET] GZip Komprimierung und Dekomprimierung mit Base64 an.
    Dort habe ich genau dasselbe gemacht, nur habe ich dort keine Probleme bei der Geschwindigkeit.



    Ich möchte aber nachher keinen Base64 String haben, sondern eine GZip Datei.
    Und da hilft mir dein Thread eben gerade nicht.

    Das mit dem Using werde ich auch noch verbessern, ist ja nicht mein Code das ganze da, und wollte jetz eben mal schnell was ausprobieren.

    Kann mir sonst noch wer helfen? :thumbsup:
    Doch, der Thread hilft dir.
    Wobei..stimmt eher nicht.

    Ein kleines Beispiel:

    VB.NET-Quellcode

    1. Using fS As New FileStream("file.gz")
    2. Using gzS As New GZipStream(fS, CompressionMode.Decompress)
    3. Using strR = New StreamReader(gzS)
    4. Return Encoding.Default.GetBytes(strR.ReadToEnd())
    5. End Using
    6. End Using
    7. End Using

    Sollte evtl. so funktionieren. Ist a) ausm Kopf und b) nach mehreren Monaten ohne VB geschrieben.
    msdn.microsoft.com/de-de/libra…io.streamreader.readtoend
    Funktioniert leider auch nicht, Convert.ToByteArray() gibt es leider nicht, dann hab ich versucht das ganze etwas anders zu lösen:

    VB.NET-Quellcode

    1. Public Function UnzipFile(ByVal sZipFile As String) As Boolean
    2. Using fS As New FileStream(sZipFile, FileMode.Open)
    3. Using gzS As New GZipStream(fS, CompressionMode.Decompress)
    4. Using fSS As New BinaryReader(gzS)
    5. Dim barr(gzS.Length) As Byte
    6. fSS.Read(barr, 0, barr.Length)
    7. File.WriteAllBytes(sZipFile.Substring(0, sZipFile.Length - 3), barr)
    8. End Using
    9. End Using
    10. End Using
    11. End Function


    Leider wird mir dann bei der Zeile:

    VB.NET-Quellcode

    1. Dim barr(gzS.Length) As Byte
    ein Fehler ausgegeben: Dieser Vorgang wird leider nicht unterstützt. Und Jetzt? 8o

    Edit: Habe dein Edit zu spät gesehen, probiere es gerade aus.
    Du hattest noch nen Edit gemacht, richtig? Habs jetzt dann nochmal probiert, er wirft zwar kein Fehler aus, aber die Datei wird nicht erstellt. :(

    Edit: Er erstellt die Datei, allerdings ist diese nicht vollständig. Die komprimierte Datei ist 3,48 MB groß. Original Unkomprimiert 6,71 Mb und die die rauskommt wenn ich sie dekomprimiere: 6,49 ...
    hmm...warum wohl?
    Guck dir mal den Rückgabewert von ReadToEnd: String.
    Dann musst du dir daraus ein ByteArray machen: Encoding.Default.GetBytes(String).
    Jetzt guck dir mal genau in der Mitte das Wörtchen "Return" an: es gibt den Wert der Funktion zurück: die Funktion wird beendet.
    Was du nun machen musst: Die Ausgabe des StreamReaders in eine Datei schreiben. Dazu solltest du dir evtl. mal den BinaryWriter und den StreamWriter sowie die .Write-Parameter der Streams ansehen.

    VB.NET-Quellcode

    1. Public Function UnzipFile(ByVal sZipFile As String) As Boolean
    2. Using fS As New FileStream(sZipFile, FileMode.Open)
    3. Using gzS As New GZipStream(fS, CompressionMode.Decompress)
    4. Using StrR As New StreamReader(gzS)
    5. File.WriteAllBytes("C:\Users\Johannes\Desktop\Neuz.exe", System.Text.Encoding.Default.GetBytes(StrR.ReadToEnd))
    6. End Using
    7. End Using
    8. End Using
    9. End Function


    So sieht der Code jetzt aus. Macht File.WriteAllBytes nicht dasselbe wie z.B. ein Binary Reader mit den Write Parameter?

    Edit: So klappts auch nicht, dasselbe Resultat:

    VB.NET-Quellcode

    1. Public Function UnzipFile(ByVal sZipFile As String) As Boolean
    2. Using fS As New FileStream(sZipFile, FileMode.Open)
    3. Using gzS As New GZipStream(fS, CompressionMode.Decompress)
    4. Using StrR As New StreamReader(gzS)
    5. Dim bArr(StrR.ReadToEnd.Length) As Byte
    6. Using BW As New FileStream("C:\Users\Johannes\Desktop\Neuz.exe", FileMode.Create)
    7. BW.Write(bArr, 0, bArr.Length)
    8. End Using
    9. End Using
    10. End Using
    11. End Using
    12. End Function

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Killerjo96“ ()

    Benütz Mal deinen Code vom ersten Post mit dem Originalteil. Ersetze dabei bei Zeile 15 und 16 "100" durch "1024" oder vielleicht mehr. Ich hab bei mir jeweils 8192 benützt.

    Hintergrund: vergrössere die Blöcke.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „alca“ ()

    Bisher ist hier nur ? gepostet worden.

    Wenn du eine unkomprimierte Datei erstellen willst, dann musste die komprimierte halt mit einem GZipStream öffnen, blockweise aus dem auslesen, und die ausgelesenen Blöcke direkt in einen FileStream schreiben (der die dekomprimierte Datei schreibt).
    Also einfach blockweise von einen Stream in den anneren schreiben - kein Encoding, kein Redim Preserve.
    gugge vlt. Stream-Konzepte

    ErfinderDesRades schrieb:

    Wenn du eine unkomprimierte Datei erstellen willst, dann musste die komprimierte halt mit einem GZipStream öffnen, blockweise aus dem auslesen, und die ausgelesenen Blöcke direkt in einen FileStream schreiben (der die dekomprimierte Datei schreibt).
    Also einfach blockweise von einen Stream in den anneren schreiben - kein Encoding, kein Redim Preserve.
    gugge vlt. Stream-Konzepte


    Danke, werde ich mir mal anschauen ;)