Domanda

Devo implementare un'implementazione ZLib speciale che dovrebbe funzionare sotto .Net e Mono. I messaggi di dati / stringa vengono ricevuti tramite un socket e quindi manca il checksum. Si tratta di dati di stringa grezzi, non di file.

    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
};

Ho provato a decomprimere i dati con GZipStream e DeflateStream, ma penso che GZStream fallisca a causa del checksum mancante. Ho anche provato vari offset, ma non ho avuto fortuna. Il checksum non viene utilizzato perché i dati vengono comunque ricevuti tramite un socket, pertanto il checksum ZLib sarebbe un sovraccarico aggiuntivo. Ho perso qualcosa o potresti spiegarmi come aggiungere il checksum e chiamare la libreria giusta allora o dovrei guardare una libreria di terze parti che supporta Mono e .Net? Modifica: le prestazioni sono molto importanti in quanto ciò è stato fatto almeno una volta al secondo. Mi consiglieresti alla fine di usare il C-Lib tramite Interop? Ricevo sempre un'eccezione di dati non validi al momento e presumo che sia correlato a un checksum errato. Questo è il codice reale che ho provato a usare senza successo:

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);
È stato utile?

Soluzione

Sei sicuro che abbia a che fare con il checksum?

Il checksum a 32 bit non è facoltativo nel formato GZIP. Non capisco cosa intendi con "i dati vengono ricevuti tramite socket, quindi manca il checksum". Non importa se si ottengono i dati tramite piccione viaggiatore; se è un flusso GZIP valido, deve avere un CRC a 32 bit. Chi o cosa ha prodotto i dati di origine?

Esiste una parte opzionale nelle specifiche GZIP: il checksum a 16 bit. (La sua inclusione non è inoltre basata su come è stato creato il bytestream GZIP.) La classe System.IO.GZipStream accetterà volentieri un flusso GZIP privo di questo CRC16, oltre a uno che lo include.

Hai altri problemi nel codice. La lunghezza effettiva del buffer nel tuo codice: che cos'è? Non è certamente la lunghezza del buffer a contenere i dati decompressi. Questo è 10x. Ma 10x sembra abbastanza arbitrario. Per dati molto comprimibili, è possibile superare 10 volte. Ti suggerisco di utilizzare un approccio di streaming in decompressione.

Per quanto riguarda la capacità di gestire una decompressione all'1 secondo, sì, System.IO.GZipStream sarà abbastanza veloce per blocchi di dati abbastanza piccoli. Probabilmente non è necessario andare in una libreria C / C ++ nativa.

ps: la DotNetZip include un GZipStream che è open source; puoi usarlo fuori dalla scatola o se vuoi, puoi semplicemente prendere le cose di GZip se è tutto ciò di cui hai bisogno.

Altri suggerimenti

Basta usare DeflateStream invece di GZipStream.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top