我需要实现一个特殊的 ZLib 实现,它应该在 .Net 和 Mono 下运行。数据/字符串消息是通过套接字接收的,因此校验和丢失。这是关于原始字符串数据,而不是关于文件。

    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);
有帮助吗?

解决方案

您确定这与校验和有关吗?

在 GZIP 格式中,32 位校验和不是可选的。我不明白“数据是通过套接字接收的,因此校验和丢失”是什么意思。是否通过信鸽获取数据并不重要;如果它是有效的 GZIP 流,则它必须具有 32 位 CRC。谁或什么产生了源数据?

GZIP 规范中有一个可选部分 - 16 位校验和。(它的包含也不取决于 GZIP 字节流的创建方式。)System.IO.GZipStream 类将很乐意接受缺少此 CRC16 的 GZIP 流以及包含它的 GZIP 流。

您的代码中还有其他一些问题。你的代码中的actualBufferLength - 那是什么?当然不是保存解压数据的缓冲区的长度。那是 10 倍。但 10 倍似乎相当随意。对于非常可压缩的数据,您可能会超过 10 倍。我建议你使用流式解压的方式。

至于是否能够处理每秒 1 次的解压缩,是的,System.IO.GZipStream 对于足够小的数据块来说足够快。可能不需要使用本机 C/C++ 库。

附:这 点网压缩 库包括一个开源的 GZipStream;你可以开箱即用,或者如果你愿意的话,你可以直接获取 GZip 的东西(如果这就是你所需要的)。

其他提示

只需使用 DeflateStream 而不是 GZipStream。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top