4

zlib 的 deflate 函数接受一个Z_FULL_FLUSH选项作为其参数,据我所知,当执行完全刷新时,(0,0,0xFF,0xFF)将设置一个完全刷新点,后续数据将独立于该点之前的字节,因此使压缩数据准随机访问。我读过一点dictzip的来源,它利用这个特性来实现它的块级随机可访问性,同时保持与 gzip 的兼容性。我想使用 CLR 提供的功能重新实现 dictzip 压缩器/解压缩器。解压器(随机部分读取器)很简单,我可以用DeflateStream逐块解压数据,没有问题,但是创建有很大的障碍,DeflateStream的API太高级了,似乎所有放气细节都是隐藏的,因此无法利用。我真的不喜欢在我的 C# 项目中包含 C 共享库,它使跨平台部署非常痛苦,并且首先取消了选择 C# 编码的好处。所以,我应该怎么办?有什么方法可以仅使用托管代码来绕过这个障碍?Mono 是否为 zlib 提供了较低级别的包装器,以便我可以使用完全刷新选项调用 deflate?任何建议将被认真考虑!

--- >8 ---

感谢提供答案的 Mark Adler。DotNetZip(特别是 Ionic.Zlib.DeflateStream)完全支持我要求的功能。下面的例子展示了它是如何工作的:

        Encoding u8 = Encoding.UTF8;
        byte[]  s1 = u8.GetBytes("the quick brown fox "),
                s2 = u8.GetBytes("jumps over the lazy dog!");
        var ms = new MemoryStream(100);
        var deflator = new DeflateStream(ms, CompressionMode.Compress, true);
        deflator.FlushMode = FlushType.Full;
        deflator.Write(s1, 0, s1.Length);
        deflator.Flush();
        var pos = ms.Position;//remember the full flush point
        deflator.Write(s2, 0, s2.Length);
        deflator.Dispose();

        var inflator = new DeflateStream(ms, CompressionMode.Decompress);
        ms.Position = pos;
        byte[] buf = new byte[100];
        inflator.Read(buf, 0, s2.Length);
        Console.WriteLine(u8.GetString(buf));//output: jumps over the lazy dog!
4

1 回答 1

2

试试DotNetZip。所以不会让我发布少于 30 个字符,即使这是一个完整且正确的答案,所以我添加了这个无关的句子。

于 2012-11-26T18:59:21.863 回答