Zlib Deflate的同步刷新

4
我需要一个zlib deflate压缩流。在我的实现中,我必须在整个会话期间使用单个流。在此期间,小块数据将通过压缩流传递。每次传递块时,它必须立即以压缩形式发送。
我的第一次尝试是使用DeflateStream,但当我发送第一个块时,其压缩数据直到关闭流才出现。
阅读有关 zlib flush modes的内容,似乎有一个特定模式适用于我所需的内容。
1. 我是否使用了正确的类(DeflateStream)进行zlib deflate压缩? 2. 如何启用“同步刷新”行为?
3个回答

2
该项目 DotNetZip 有一个名为Zlib的子模块,其中包含自己的DeflateStream实现。
该实现还有另一个名为FlushMode的属性:
DeflateStream deflate = new DeflateStream(stream, CompressionMode.Compress);
deflate.FlushMode = FlushType.Sync;
deflate.Write (data, 0, data.Length);
//No call to deflate.Flush() needed, automatically flushed on every write.

很遗憾,这个库不支持异步方法。虽然压缩本身不受异步操作的好处(它是CPU绑定的),但底层流通常会从网络发送/接收中受益。 - Ramon de Klein

0

确实只有在关闭时才会刷新。每次都需要使用不同的DeflateStream实例,传递true重载构造函数,告诉它在关闭DeflateStream时不要关闭底层流。


很抱歉,这不是一个选项,因为该流以一个预定义的900字节的初始化块开始,因此我的要求是单个运行流。 - hultqvist

0
回答你关于如何启用“同步刷新”行为的问题,你应该查看zlib源代码中的zpipe.c示例。
将第一行替换为下面显示的第二行:

Deflate()每当输出缓冲区满或输入缓冲区为空时都会返回, 同时附加到压缩流中一个空的文字块,也称为“同步刷新”,除了在结束时使用Z_FINISH标志。

    flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
    flush = feof(source) ? Z_FINISH : Z_SYNC_FLUSH;
    ret = deflate(&strm, flush);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接