如何在C ++中使用libbz2库解压缩内存缓冲区中的pbzip2数据

时间:2016-02-11 04:40:31

标签: bzip2 compression data-compression libzip

我有一个解压缩bzip2数据的工作版本,我称之为bz2_bzdecompress API。它就是这样的

while (bytes_input < len) {
    isDone = false;

    // Initialize the input buffer and its length
    size_t in_buffer_size = len -bytes_input;
    the_bz2_stream.avail_in = in_buffer_size;
    the_bz2_stream.next_in = (char*)data +bytes_input;

    size_t out_buffer_size =
        output_size -bytes_uncompressed;  // size of output buffer
    if (out_buffer_size == 0) {  // out of space in the output buffer
      break;
    }

    the_bz2_stream.avail_out = out_buffer_size;
    the_bz2_stream.next_out =
        (char*)output +bytes_uncompressed;  // output buffer

    ret = BZ2_bzDecompress(&the_bz2_stream);
    if (ret != BZ_OK && ret != BZ_STREAM_END) {
      throw Bzip2Exception("Bzip2 failed. ", ret);
    }

   bytes_input += in_buffer_size - the_bz2_stream.avail_in;
   bytes_uncompressed += out_buffer_size - the_bz2_stream.avail_out;

    *data_consumed =bytes_input;

    if (ret == BZ_STREAM_END) {
      ret = BZ2_bzDecompressEnd(&the_bz2_stream);
      if (ret != BZ_OK) {
        throw Bzip2Exception("Bzip2 fail. ", ret);
      }
      isDone = true;
    }
  }

这适用于本机bzip2压缩文件,但适用于pbzip2(Parallel Bzip2)和&#34; Splittable&#34; bzip2数据,它会抛出一个&#34; BZ_PARAM_ERROR&#34;。

我看到他们的文档中的pbzip2说明了这个 -

  

使用pbzip2压缩的数据被分成多个流和每个流   流是bzip2压缩看起来像这样:   [----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | - ----]

     

如果您正在使用libbzip2编写软件来解压缩创建的数据   使用pbzip2,您必须考虑数据包含   多个bzip2流,因此您将遇到流末尾标记   从每个流后的libbzip2,必须预先看看是否有   在退出之前还有更多要处理的流。 bzip2程序   本身会自动处理这种情况。

来源:http://compression.ca/pbzip2/

有人可以告诉我如何处理这个问题吗?我应该使用其他一些libzip2 API吗?

此外,pbzip2文件与普通的&#34; bunzip2&#34;兼容。命令。当我的代码抛出BZ_PARAM_ERROR时,bzip2如何正常处理?

感谢。

1 个答案:

答案 0 :(得分:2)

BZ2_bzDecompressEnd()之后,您需要再次呼叫BZ2_bzDecompressInit()(您必须在该循环之前调用它),如果仍有数据要解压缩,即bytes_input < len

要解压缩每个|-----|块,您需要执行init,一些decompress次呼叫和end。因此,如果您仍有输入,则需要执行另一项init n * decompressend

确保您执行最终end,以避免大量内存泄漏。

您正在尝试使用未初始化的BZ_PARAM_ERROR来解压缩bz_stream。执行BZ2_bzDecompressEnd()后,您不能再使用bz_stream,除非您对BZ2_bzDecompressInit()进行了 <itext creationdate="@DateTime.Now.ToString()" producer="RazorPDF"> @RenderBody() </itext>