.gz BLOB zu String (Text)

  • VB.NET
  • .NET 4.5

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Radinator.

    .gz BLOB zu String (Text)

    Moin!

    Ich lese aus einer Datenbank (MySQL) einen BLOB aus und speichere diesen als Datei.

    VB.NET-Quellcode

    1. ​Dim cmd As New MySqlCommand
    2. Dim commandstring As String = "SELECT `Data` FROM `" + table + "` WHERE `Name` LIKE '" + name + "'"
    3. Dim rdr As MySqlDataReader
    4. With cmd
    5. .Connection = mysqlconnection
    6. .CommandText = commandstring
    7. rdr = .ExecuteReader()
    8. While rdr.Read
    9. If rdr.HasRows Then
    10. My.Computer.FileSystem.WriteAllBytes("C:\Users\z00391uv.AD001\Desktop\TestOrdner\test.gz", rdr(0), False)
    11. End If
    12. End While
    13. rdr.Dispose()


    (Code ist nur ein Ausschnitt)

    Das klappt soweit gut. Im erzeugten GZ Archiv befindet sich eine Datei mit dem name test (wie das Archiv, ohne Endung, das ist so in Ordnung, die Datei kann ich auch öffnen, alles paletti). Jetzt könnte ich das Archiv entpacken und dann das File als Text auslesen. Aber ich möchte das, was

    VB.NET-Quellcode

    1. ​rdr(0)


    als byte() ausgibt gern direkt an GZipStream übergeben und dann im Endeffekt den Inhalt des Files als String haben, ohne jemals das Filesystem berührt zu haben.

    Ist das möglich und wenn ja, wie? Ich stehe da wohl auf dem Schlauch....
    Okay, vielen Dank. Ich hab das mal schnell gebaut: (rdr(0) --> DATEN, rdr(1) --> länge der Daten, kommt per SQL:

    SQL-Abfrage

    1. SELECT `Data`, length(`Data`) FROM `K1AI01120110R2A_2017-07-31_08-24` WHERE `Name` LIKE 'folge11.src'
    )

    VB.NET-Quellcode

    1. Dim memStream As New MemoryStream()
    2. memStream.Write(rdr(0), 0, rdr(1))
    3. MsgBox(memStream.Length.ToString)
    4. Dim res As String
    5. Using decompress = New GZipStream(memStream, CompressionMode.Decompress)
    6. Using sr = New StreamReader(decompress)
    7. res = sr.ReadToEnd()
    8. End Using
    9. End Using
    10. MsgBox(res)


    Die Variable memStream hat eine Länge, also alles gut. Aber irgendwas muss noch beim Decompress schief gehen... Denn "res" ist am Ende leer...

    UPDATE:

    Ich hab es noch mal so probiert:

    VB.NET-Quellcode

    1. ​Dim memStream As New MemoryStream()
    2. Dim output As String
    3. memStream.Write(rdr(0), 0, rdr(1))
    4. MsgBox("Länge MemStream: " + memStream.Length.ToString + " Länge laut SQL: " + rdr(1).ToString)
    5. Using bigStream = New GZipStream(memStream, CompressionMode.Decompress)
    6. Using bigStreamOut = New MemoryStream()
    7. bigStream.CopyTo(bigStreamOut)
    8. output = Encoding.UTF8.GetString(bigStreamOut.ToArray())
    9. End Using
    10. End Using
    11. MsgBox(output)

    Aber wieder ist das Ergebnis leer ;(

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

    Naja nach dem Write ist die Position des MemoryStreams am Ende, du musst die Position wieder auf 0 setzen.

    Wenn rdr(0).Length immer gleich rdr(1) ist, dann würd ich den konstruktor oben bevorzugen, dann sparst dir nen copy, ne allozierung und das rücksetzen der Position, ansonsten:
    msdn.microsoft.com/de-de/library/63z365ty(v=vs.110).aspx
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Okay, meine endgültige Lösung sieht in etwa so aus:

    VB.NET-Quellcode

    1. ​Function DecompressASCII(compressedString As Byte()) As String
    2. Using ms As New MemoryStream(compressedString)
    3. Using gzStream As New GZipStream(ms, CompressionMode.Decompress)
    4. Using sr As New StreamReader(gzStream, Encoding.ASCII)
    5. Return sr.ReadToEnd
    6. End Using
    7. End Using
    8. End Using
    9. End Function
    IMHO wäre es besser den Inhalt der GZIP Datei mit der Funktion nicht als String sondern als Byte-Array auszulesen.
    Beim String must du noch auf das Encoding achten. Wenn du einfach nur das Byte-Array als String speicherst (also als Folge von Hexadezimalen Zahlenpaaren - CF0DBA08... usw) kannst du das Ganze speichern, ohne dir Sorgen machen zu müssen, dass beim zurückspeichern irgendein Byte-Salat raus kommt.

    Hierzu einfach lokal ein Byte Array definieren und das schöne Schlüsselwort yield verwenden.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell