Frage

Ich brauche eine spezielle ZLib Umsetzung zu implementieren, die unter .NET und Mono ausgeführt werden sollen. Die Daten / string-Meldungen werden über einen Socket empfangen und damit die Prüfsumme fehlen. Hier geht es um rohe String-Daten, nicht über Dateien.

    unsigned char zlib_header[]={
// custom additional Zlib Id
       'Z',    // Our own ID
// The normal GZIP header
       0x1f,
       0x8b,   // GZIP ID
       0x08,   // Deflated
       0x00,   // Flags
       0, 0, 0, 0, // Timestamp,
       0x00,   // Extra flags
       0x00,   // OS identifier
// afterwards compressed data without a checksum
};

Ich habe versucht, die Daten mit GZipStream und DeflateStream zu dekomprimieren, aber ich denke, dass GZStream wegen der fehlenden Prüfsumme fehl. Ich habe auch verschiedene Versätze, hatte aber kein Glück versucht. Die Prüfsumme wird nicht verwendet, da die Daten über eine Socket ohnehin empfangen wird - also die ZLib Prüfsumme zusätzlichen Aufwand wäre. Habe ich etwas verpasst oder könnten Sie mir erklären, wie die Prüfsumme hinzuzufügen und die richtige Bibliothek rufen dann oder sollte ich bei einer 3rd-Party-Bibliothek suchen, die Mono und .NET unterstützt? Edit: Die Leistung ist sehr kritisch, da dies mindestens einmal pro Sekunde. Würden Sie mir am Ende empfehlen die C-Lib über Interop zu benutzen? Ich habe immer Ungültige Daten Ausnahme zur Zeit empfangen und ich nehme an, dass es auf die falsche Prüfsumme zusammenhängt. Dies ist der eigentliche Code, die ich versuchte, ohne Erfolg zu verwenden:

const int HeaderSize = 1;
System.IO.MemoryStream ms = new System.IO.MemoryStream(compressedBuffer, HeaderSize, compressedBuffer.Length-HeaderSize);//remove the additional Z from the header
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress,true);
byte[] deCompressedBytes = new byte[actualBufferLength* 10];
int resultSize=zipStream.Read(deCompressedBytes, 0, actualBufferLength);//get rid of the header      
UTF8Encoding enc = new UTF8Encoding();
string result = enc.GetString(deCompressedBytes, 0, resultSize);
War es hilfreich?

Lösung

Sind Sie sicher, es hat mit der Prüfsumme zu tun?

Die 32-Bit-Prüfsumme ist im GZIP-Format nicht optional. Ich verstehe nicht, was Sie mit „die Daten über die Buchse empfangen wird somit die Prüfsumme fehlt“. Dabei spielt es keine Rolle, ob Sie die Daten über Brieftaube erhalten; wenn es ein gültiger GZIP Strom ist, muss es einen 32-Bit-CRC hat. Wer oder was die Quelldaten erzeugt?

Es ist ein optionaler Bestandteil in der GZIP spec - die 16-Bit-Prüfsumme. (Seine Aufnahme ist auch nicht ausgesagt, wie die GZIP Bytestrom erstellt wurde.) Die System.IO.GZipStream Klasse wird gerne einen GZIP-Stream an, die diese CRC16 fehlt, sowie eine, die es enthält.

Sie haben einige andere Probleme im Code. Die actualBufferLength in Ihrem Code - was ist das? Es ist sicherlich nicht die Länge des Puffers der dekomprimierten Daten zu halten. Das ist 10-fach. Aber 10x scheint ziemlich willkürlich. Für sehr komprimierbaren Daten, können Sie 10x überschreiten. Ich schlage vor, Sie einen Streaming-Ansatz in Dekompression verwenden.

Als ob Sie eine 1-pro-Sekunde-Dekompression zu handhaben werden in der Lage, ja, wird die System.IO.GZipStream für klein genug, um Datenmengen schnell genug sein. Es gibt wahrscheinlich keine Notwendigkeit zu einer nativen C / C ++ Bibliothek zu gehen.

ps: Der DotNetZip Bibliothek eine GZipStream enthält, die Open-Source ist; Sie können es aus der Box verwenden oder wenn Sie möchten, können Sie einfach die GZIP Sachen packen, wenn das alles ist, was Sie brauchen.

Andere Tipps

Verwenden Sie einfach DeflateStream statt GZipStream.

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