2009-05-07 47 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。