使用 zlib 进行 GZIP 压缩到缓冲区

Sh0*_*nya 8 c linux gzip zlib content-encoding

我想使用gzip压缩内存缓冲区并将压缩的字节放入另一个内存缓冲区。我想在 HTTP 数据包的有效负载中发送压缩缓冲区Content-Encoding: gzip。我可以使用zlib进行 deflate 压缩(compress()函数)轻松地做到这一点。但是,我没有看到可以满足我需要的 API ( gzip )。zlib API 是压缩并写入文件gzwrite())。但是,我想压缩并写入缓冲区。

有任何想法吗?

我在 Linux 上使用 C 语言。

Jie*_*eng 13

deflate() 默认以 zlib 格式工作,要启用 gzip 压缩,您需要使用 deflateInit2() 将 16 添加到 windowBits,如下代码所示,windowBits 是切换到 gzip 格式的关键

// hope this would help  
int compressToGzip(const char* input, int inputSize, char* output, int outputSize)
{
    z_stream zs;
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = Z_NULL;
    zs.avail_in = (uInt)inputSize;
    zs.next_in = (Bytef *)input;
    zs.avail_out = (uInt)outputSize;
    zs.next_out = (Bytef *)output;

    // hard to believe they don't have a macro for gzip encoding, "Add 16" is the best thing zlib can do:
    // "Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper"
    deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY);
    deflate(&zs, Z_FINISH);
    deflateEnd(&zs);
    return zs.total_out;
}
Run Code Online (Sandbox Code Playgroud)

标题中的一些相关内容:

“这个库也可以选择在内存中读取和写入 gzip 和原始 deflate 流。”

“向 windowBits 添加 16,以在压缩数据周围编写简单的 gzip 标头和尾部,而不是 zlib 包装器”

有趣的是 deflateInit2() 的文档距其定义有 1000 多行,除非必须,否则我不会再次准备该文档。


amr*_*shu 2

Gzip 是一种文件格式,这就是为什么提供的实用程序函数似乎在 fd 上运行,用于shm_open()创建具有足够内存的 fd mmap()。重要的是,写入的数据不会扩展映射区域的大小,否则写入将失败。这是映射区域的限制。

将 fd 传递给gzdopen().

但正如 Mark 在他的回答中所建议的,使用 Basic API接口是更好的方法。