.Net zlib inflate with .Net 4.5

本文关键字:Net inflate zlib with | 更新日期: 2023-09-27 18:19:24

根据。net 4.5 System.IO.Compression是基于zlib的。
我现在正试图将我当前基于互操作的读取从非。net服务器的zlib压缩流更改为基于BCL的实现。我的实现是这样的:

    var enc = new UTF8Encoding();            
        var readBytes = BufferSizeRaw;
        var outputBuffer = new byte[BufferSizeRaw];            
        var networkBuffer = _networkQueue.Take();
        var ms = new MemoryStream(networkBuffer.InputBuffer, 0, networkBuffer.UsedLength);
        using (Stream stream = new DeflateStream(ms, CompressionMode.Decompress))
            while (readBytes==BufferSizeRaw)
            {
                readBytes = stream.Read(outputBuffer, 0, outputBuffer.Length);                
                stringBuffer+= enc.GetString(outputBuffer, 0, readBytes);                
            }

第一次调用DeflateStream上的解压缩/读取时,我收到以下异常:

块长度与其补码不匹配

基于互操作的调用使用var result=inflate(ref zStyream, ZLibFlush.NoFlush;
有没有人尝试过相同的或看到一个原因在代码中的错误或有一个错误的理解在我的结束?我也试过截断前两个字节,没有任何运气。
前几个字节分别是20,202,177,13

.Net zlib inflate with .Net 4.5

上面的答案是正确的,但不完全清楚"为什么"。原始ZLib流的前两个字节提供了有关所使用的压缩类型的详细信息。Microsoft的System.Io.Compression中的DeflateStream类不理解这些。修复方法如下:

using (MemoryStream ms = new MemoryStream(data))
{
    MemoryStream msInner = new MemoryStream();
    // Read past the first two bytes of the zlib header
    ms.Seek(2, SeekOrigin.Begin);
    using (DeflateStream z = new DeflateStream(ms, CompressionMode.Decompress))
    {
        z.CopyTo(msInner);

在本例中,数据是带有原始Zlib文件的Byte[]。在将其加载到MemoryStream中后,我们只需"查找"前两个字节。

如果你看的是原始字节,这篇文章解释了Zlib头文件是什么样子的。

zlib头文件是什么样子的?

要压缩的数据的前几个字节是什么?

您可能有zlib、gzip或原始deflate数据,您正在尝试解码。

顺便说一下,我强烈建议您使用DotNetZip的zlib接口,而不是。NET 4.5的(或。NET任何版本)。. NET 4.5在接口上有bug,微软已经声明他们不会修复(!)。

以下是ProVega答案的修改版本,它将字节数组膨胀为字符串:

using (var stream = new MemoryStream(bytes,2, bytes.Length - 2))
using (var inflater = new DeflateStream(stream, CompressionMode.Decompress))
using (var streamReader = new StreamReader(inflater))
{
    return streamReader.ReadToEnd();
}