C# Zlib压缩不兼容IONAL.Zip、System.IO.compression和SharpCompression

C# Zlib压缩不兼容IONAL.Zip、System.IO.compression和SharpCompression,c#,compression,zlib,C#,Compression,Zlib,我正在将文件格式(OMF)移植到C#中。文件中的部分存储是zlib压缩数据数组。现有版本的文件格式化程序使用来自Ionic.Zip的静态方法读取文件,如下所示: public static byte[] Uncompress(this byte[] value) { // Uncompress return ZlibStream.UncompressBuffer(value); } 我目前正在进行的项目已经使用了SharpCompress,使用两

我正在将文件格式(OMF)移植到C#中。文件中的部分存储是zlib压缩数据数组。现有版本的文件格式化程序使用来自Ionic.Zip的静态方法读取文件,如下所示:

public static byte[] Uncompress(this byte[] value)
    {
        // Uncompress
        return ZlibStream.UncompressBuffer(value);
    }
我目前正在进行的项目已经使用了SharpCompress,使用两个不同的压缩库似乎是浪费,所以我想我应该重写它以使用SharpCompress。SharpCompress没有像Ionic那样的UncompressBuffer静态功能,因此我按照如下方式实现了它,这在我的阅读中似乎是一种非常标准的方法:

using (var originalStream = new MemoryStream(value))
        {
            using (var decompressedStream = new MemoryStream())
            {
                using (var decompressor = new ZlibStream(originalStream, CompressionMode.Decompress))
                {
                    decompressor.CopyTo(decompressedStream);
                    return decompressedStream.ToArray();
                }
            }
        }
我还尝试了一种类似的方法,使用System.IO.Compression.DeflateStream类,遵循MSDocs提供的模式。但是,在这两种情况下,在CopyTo函数调用中,我都会得到一个异常,表明数据存在问题:

对于Zlib:“Zlib异常:错误状态(不正确的数据检查)”

对于Windows:“块长度与其补码不匹配”

这可能是我缺少的东西,它将UncompressBuffer函数的函数与这种解压缩方法区分开来,但似乎UncompressBuffer函数与Zlib类的内部部分一起工作


我做错了什么?这两个zip库的实现之间是否存在差异,导致它们不兼容?

下面的代码运行,这表明至少有使用Ionic.zip和SharpCompress的基线往返功能。这表明您试图解压缩的负载可能有一些特定的微妙之处

class Program
{
    static void Main(string[] args)
    {
        var rnd = new Random(0);
        var raw = new byte[1024];
        rnd.NextBytes(raw);
        raw = System.Text.Encoding.UTF8.GetBytes(System.Convert.ToBase64String(raw));

        var ionicCompressed = Ionic.Zlib.ZlibStream.CompressBuffer(raw);
        var sharpCompressed = DoSharpCompress(raw);

        var ionicDecompressIonic = Ionic.Zlib.ZlibStream.UncompressBuffer(sharpCompressed);
        var ionicDecompressSharp = Ionic.Zlib.ZlibStream.UncompressBuffer(ionicCompressed);


        var sharpDecompressSharp = DoSharpDecompress(sharpCompressed);
        var sharpDecompressIonic = DoSharpDecompress(ionicCompressed);

        AssertEqual(ionicDecompressIonic, ionicDecompressSharp);
        AssertEqual(sharpDecompressSharp, sharpDecompressIonic);
        AssertEqual(ionicDecompressSharp, sharpDecompressIonic);
        AssertEqual(raw, sharpDecompressIonic);

        Console.WriteLine(System.Text.Encoding.UTF8.GetString(raw));
        Console.WriteLine(System.Text.Encoding.UTF8.GetString(sharpDecompressIonic));

        Console.WriteLine(System.Text.Encoding.UTF8.GetString(raw) == System.Text.Encoding.UTF8.GetString(sharpDecompressIonic));

        Console.ReadLine();
    }

    static byte[] DoSharpCompress(byte[] uncompressed)
    {
        var sc1 = new SharpCompress.Compressors.Deflate.ZlibStream(new MemoryStream(uncompressed), SharpCompress.Compressors.CompressionMode.Compress);
        var sc2 = new MemoryStream();
        sc1.CopyTo(sc2);
        return sc2.ToArray();
    }

    static byte[] DoSharpDecompress(byte[] compressed)
    {
        var sc1 = new SharpCompress.Compressors.Deflate.ZlibStream(new MemoryStream(compressed), SharpCompress.Compressors.CompressionMode.Decompress);
        var sc2 = new MemoryStream();
        sc1.CopyTo(sc2);
        return sc2.ToArray();
    }

    static bool AssertEqual(byte[] a, byte[] b)
    {
        if (!a.SequenceEqual(b))
            throw new Exception();
        return true;
    }
}

下面的代码运行,这表明至少有使用Ionic.Zip和SharpCompress的基线往返功能。这表明您试图解压缩的负载可能有一些特定的微妙之处

class Program
{
    static void Main(string[] args)
    {
        var rnd = new Random(0);
        var raw = new byte[1024];
        rnd.NextBytes(raw);
        raw = System.Text.Encoding.UTF8.GetBytes(System.Convert.ToBase64String(raw));

        var ionicCompressed = Ionic.Zlib.ZlibStream.CompressBuffer(raw);
        var sharpCompressed = DoSharpCompress(raw);

        var ionicDecompressIonic = Ionic.Zlib.ZlibStream.UncompressBuffer(sharpCompressed);
        var ionicDecompressSharp = Ionic.Zlib.ZlibStream.UncompressBuffer(ionicCompressed);


        var sharpDecompressSharp = DoSharpDecompress(sharpCompressed);
        var sharpDecompressIonic = DoSharpDecompress(ionicCompressed);

        AssertEqual(ionicDecompressIonic, ionicDecompressSharp);
        AssertEqual(sharpDecompressSharp, sharpDecompressIonic);
        AssertEqual(ionicDecompressSharp, sharpDecompressIonic);
        AssertEqual(raw, sharpDecompressIonic);

        Console.WriteLine(System.Text.Encoding.UTF8.GetString(raw));
        Console.WriteLine(System.Text.Encoding.UTF8.GetString(sharpDecompressIonic));

        Console.WriteLine(System.Text.Encoding.UTF8.GetString(raw) == System.Text.Encoding.UTF8.GetString(sharpDecompressIonic));

        Console.ReadLine();
    }

    static byte[] DoSharpCompress(byte[] uncompressed)
    {
        var sc1 = new SharpCompress.Compressors.Deflate.ZlibStream(new MemoryStream(uncompressed), SharpCompress.Compressors.CompressionMode.Compress);
        var sc2 = new MemoryStream();
        sc1.CopyTo(sc2);
        return sc2.ToArray();
    }

    static byte[] DoSharpDecompress(byte[] compressed)
    {
        var sc1 = new SharpCompress.Compressors.Deflate.ZlibStream(new MemoryStream(compressed), SharpCompress.Compressors.CompressionMode.Decompress);
        var sc2 = new MemoryStream();
        sc1.CopyTo(sc2);
        return sc2.ToArray();
    }

    static bool AssertEqual(byte[] a, byte[] b)
    {
        if (!a.SequenceEqual(b))
            throw new Exception();
        return true;
    }
}