【问题标题】:Does any mainstream compression algorithm natively support streaming data是否有任何主流压缩算法原生支持流数据
【发布时间】:2017-06-10 21:30:49
【问题描述】:

是否有任何主流压缩算法,例如snappyzlibbzip 原生支持跨网络的流式数据?例如,如果我必须发送一个压缩的有效负载,那么我是否必须在发送消息之前手动添加有效负载的大小?或者是否有任何库提供 API 来判断给定 x 字节的消息是否完整?

【问题讨论】:

  • 几乎按照定义,流式 API 将无法跟踪消息边界。这是调用者的责任。
  • @JamesKPolk 那么人们在消息之前对消息大小进行编码的通常方式是什么?手动整数编码?
  • 如果只有一条消息,那么您可以阅读直到逻辑 EOF。否则,您可以为整数计数添加前缀,或使用一些唯一的分隔符。

标签: sockets compression zlib bzip2 snappy


【解决方案1】:

zlib、bzip2、lz4、zstd、brotli、lzma2 和许多其他都通过在压缩数据中使用数据结束标记来支持流式传输。

碰巧的是,您提到的其中一个 snappy 在您所要求的意义上不可流式传输,因为格式以未压缩大小开始。

【讨论】:

    【解决方案2】:

    Zstd 可以。有一个 ZSTD_compressStream()/ZSTD_decompressStream() API。

    https://github.com/facebook/zstd/tree/dev/examples

    伪代码如下:

    // Create stream       
    ZSTD_CStream* const cstream = ZSTD_createCStream();
    
    // Init stream
    size_t const initResult = ZSTD_initCStream(cstream, cLevel);
    size_t read, toRead;
    
    while((read = fread(buffer, 1, toRead, file)) ) {
        ZSTD_inBuffer input = { buffIn, read, 0 };
    
        // Process next chunk
        while (input.pos < input.size) {
            ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
    
            // Compress Data
            toRead = ZSTD_compressStream(cstream, &output , &input);  
            [...]
            fwrite_orDie(buffOut, output.pos, fout);
       }
    }
    
    ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
    
    // End stream
    ZSTD_endStream(cstream, &output);  
    [...]
    // Free stream
    ZSTD_freeCStream(cstream);
    

    【讨论】:

    • 谢谢!您介意使用允许您流式传输的 API 的要点更新您的答案吗?这个例子有点难以解析,如果我自己做出推论,我觉得我会错过一些关键点
    • 不确定这是您要查找的内容,但我使用一些伪代码编辑了答案,其中包含使用流 API 压缩缓冲区的不同步骤(来自示例)。
    • 很抱歉我之前不清楚。在不知道数据包含什么或传入多少数据之后,我一直在寻找一种解压缩数据的方法。
    • @flanglet,Zstd 记录流状态大小,就像它对 DEFLATE-streams 所做的那样...SLZ libslz.org(“虽然 zlib 除了几十流描述符本身的字节数,SLZ 只存储由 28 个字节组成的流描述符。")?
    • @osgx 我能找到的最佳答案在这里:fastcompression.blogspot.com/2016/04/…
    【解决方案3】:

    还有 DEFLATE(zlib 兼容)无状态 SLZ 用于流式传输(仅压缩)到每个流的状态内存减少的许多客户端:http://www.libslz.org/“无状态 ZIP 库 - SLZ”:

    SLZ 是一种快速且无内存的流压缩器,可生成可使用 zlib 或 gzip 解压缩的输出。它根本没有实现解压,zlib 非常适合这个。 目的是在需要与 zlib 兼容的流并且 zlib 的资源使用率过高而压缩比并不重要的情况下使用 SLZ。典型的用例是在 HTTP 服务器和网关中,它们必须以很少的 CPU 资源并行压缩许多流来分配给此任务,并且不必因内存使用而限制压缩率。在这样的环境下,服务器的内存使用量很容易除以 10,CPU 使用量除以 3。此外,它的高性能使其填补了网络备份应用程序的空白。

    虽然 zlib 每个流使用 256 kB 的内存以及流描述符本身的几十个字节,但 SLZ 仅存储由 28 个字节组成的流描述符。因此,它特别适合需要处理数万到数十万并发流的环境。

    zlib 和 SLZ 之间的主要区别在于 SLZ 是无状态的,因为它不会将先前压缩的数据视为其字典的一部分。当它以足够大的块(一次至少几个 kB)输入时,它不会损害压缩性能

    【讨论】:

    • zlib (deflate) 按原样支持流式传输。 “无状态”业务只是在许多个压缩线程的情况下减少内存使用,尽管以压缩效率为代价。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多