2009-05-07 50 views
0

我需要實現一個特殊的ZLib實現,它應該在.Net和Mono下運行。 數據/字符串消息通過套接字接收,因此校驗和丟失。 這是關於原始字符串數據,而不是關於文件。Zlib for Mono/.Net沒有一個已知的校驗和

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

我曾嘗試與解壓縮和GZipStream的DeflateStream數據,但我認爲GZStream失敗,因爲缺少校驗和。我也嘗試了各種補償,但沒有運氣。 不使用校驗和,因爲無論如何都是通過套接字接收數據的 - 因此ZLib校驗和會是額外的開銷。 我錯過了什麼,或者你能解釋我如何添加校驗和並調用正確的庫,或者我應該看看支持Mono和.Net的第三方庫嗎? 編輯:性能非常關鍵,因爲這至少每秒完成一次。你會推薦我最後通過Interop使用C-Lib嗎? 我現在總是收到無效數據異常,並且我認爲它與錯誤的校驗和有關。 這是我嘗試沒有成功使用的實際代碼:

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

回答

2

您確定它與校驗和有關嗎?

32位校驗和在GZIP格式中不是可選的。我不明白你的意思是「通過套接字接收數據,因此校驗和丟失了」。如果你通過信鴿獲得數據並不重要;如果它是有效的GZIP流,則它必須具有32位CRC。誰或什麼產生了源數據?

GZIP規範中有一個可選部分 - 16位校驗和。 (它的包含也不是以創建GZIP字節流的方式爲依據的。)System.IO.GZipStream類將很樂意接受一個缺少這個CRC16的GZIP流,也包含一個包含它的GZIP流。

您在代碼中還有其他一些問題。你的代碼中的actualBufferLength - 那是什麼?當然不是保存解壓縮數據的緩衝區的長度。那是10倍。但10倍似乎很隨意。對於非常可壓縮的數據,您可能會超過10倍。我建議你在解壓縮中使用流式方法。

至於您是否能夠處理每秒1次的解壓縮,是的,System.IO.GZipStream對於足夠小的數據塊來說足夠快。可能不需要去本地C/C++庫。

ps:DotNetZip庫包含一個開源的GZipStream;你可以直接使用它,或者如果你喜歡,你可以抓住GZip的東西,如果這是你需要的。

+0

我正在與遠程位置的第三方進行整合,他們的軟件中顯然存在一個錯誤 - 他們沒有正確刷新網絡流。還是要謝謝你的幫助。 – weismat 2009-05-10 05:51:22

1

只需使用的,而不是GZipStream DeflateStream。