【问题标题】:can I reuse zlib's z_stream for several operations?我可以将 zlib 的 z_stream 用于多个操作吗?
【发布时间】:2016-09-15 14:31:52
【问题描述】:

我目前正在玩zlib

通常的例子或多或少如下(C/C++伪代码)

z_stream zs;
memset(&zs, 0, sizeof(zs));

if (deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK)
    return false;

zs.next_in  = input_data;
zs.avail_in = input_size;

zs.next_out  = output_data;
zs.avail_out = output_size;

int result = deflate(&zs, Z_FINISH);

deflateEnd(&zs);

return result == Z_STREAM_END ? true : false;

使用 valgrind 我发现 deflateInit 和 memset 并不是完全“免费”的操作,而是需要相当长的时间。

我的问题是,我可以重复使用 z_streamdeflateInit 吗?
例如我可以通过更新缓冲区多次放气吗?

【问题讨论】:

  • 为什么不自己测试一下呢?
  • 如果我测试它并奇迹般地工作,它仍然不意味着它是正确的。它可以将数据“添加”到之前的“部分”或其他内容。

标签: c++ c zlib


【解决方案1】:

是的。您可以使用deflateReset()deflateEnd() 后跟deflateInit() 具有相同的效果,但完全避免了代价高昂的取消和重新分配。

【讨论】:

  • 我希望你能看到这个问题 :) LP 的回答添加了一些自动调用 deflateEnd 的信息。在此之后deflateReset 安全吗? InflateReset 的情况一样吗?
  • 没有deflateEnd()的自动调用。您不能在 deflateEnd() 之后调用 deflateReset()。是的,inflateReset() 是对应的 inflate 调用。
  • 顺便提一下,当我重置结构时,我的放气功能增加了 33%。
  • 33% 增加了什么?
  • deflate 与使用 init / end 的 deflate 相比,reset 的执行速度快 33%。可能我对结果过于兴奋并跳过了一些单词。
【解决方案2】:

看着the man

[...]我们要做的第一件事是使用 deflateInit() 初始化 zlib 状态以进行压缩。 这必须在第一次使用 deflate() 之前完成。 [..]

强调我的

关键词是第一次使用之前。只要下次放气使用相同的配置,您就可以调用它一次。

还有

[...]如果从输入文件中读取错误,则进程中止,调用 deflateEnd() 以释放分配的 zlib 状态,然后返回错误。我们不想要内存泄漏,不是吗? deflateEnd() 可以在状态初始化后随时调用。完成后,必须调用 deflateInit()(或 deflateInit2())来开始新的压缩过程。[...]

强调我的

【讨论】:

  • 正确。通过查看 zlib 代码,可以看出 z_stream 在错误时最终确定,在成功处理时可以重用该结构。
  • 谢谢。出于某种原因,我没有手册页,也没有在他们的网站上找到它。
  • 我可能需要 deflateReset
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多