gpt4 book ai didi

c - 使用 bzip2 低级例程压缩数据 block

转载 作者:行者123 更新时间:2023-12-02 03:55:02 37 4
gpt4 key购买 nike

概览

我正在使用 libbzip2 中的低级调用图书馆:BZ2_bzCompressInit() , BZ2_bzCompress()BZ2_bzCompressEnd()将数据块压缩到标准输出。

我正在从更高级别的调用中迁移工作代码,因为我有一个字节流进来,我想将这些字节压缩为一组离散块(离散块是一组包含一组感兴趣的标记的字节)我的输入在逻辑上分为这些块的组)。

一组完整的块可能包含 500 个块,我想将其压缩为一个 bzip2 流并写入标准输出。

在一组中,使用我在下面概述的伪代码,如果我的示例缓冲区一次能够容纳 101 个块,我将打开一个新流,在 101、101、101、101 和最后一次运行中压缩 500 个块关闭流的 96 个块。

问题

问题是我的 bz_stream结构实例,它在 BZ2_bzCompress() 的单次传递中跟踪压缩字节数例程,似乎声称写入的压缩字节数比最终压缩文件中的总字节数多。

例如,压缩输出可能是一个真实大小为 1234 字节的文件,而报告的压缩字节数(我在调试时跟踪)略高于 1234 字节(比如 2345 字节)。

我的粗略伪代码分为两部分。

第一部分是我如何压缩块子集的粗略草图(我知道在这个子集之后还有另一个子集):

bz_stream bzStream;
unsigned char bzBuffer[BZIP2_BUFFER_MAX_LENGTH] = {0};
unsigned long bzBytesWritten = 0UL;
unsigned long long cumulativeBytesWritten = 0ULL;
unsigned char myBuffer[UNCOMPRESSED_MAX_LENGTH] = {0};
size_t myBufferLength = 0;

/* initialize bzStream */
bzStream.next_in = NULL;
bzStream.avail_in = 0U;
bzStream.avail_out = 0U;
bzStream.bzalloc = NULL;
bzStream.bzfree = NULL;
bzStream.opaque = NULL;
int bzError = BZ2_bzCompressInit(&bzStream, 9, 0, 0);

/* bzError checking... */

do
{
/* read some bytes into myBuffer... */

/* compress bytes in myBuffer */
bzStream.next_in = myBuffer;
bzStream.avail_in = myBufferLength;
bzStream.next_out = bzBuffer;
bzStream.avail_out = BZIP2_BUFFER_MAX_LENGTH;
do
{
bzStream.next_out = bzBuffer;
bzStream.avail_out = BZIP2_BUFFER_MAX_LENGTH;
bzError = BZ2_bzCompress(&bzStream, BZ_RUN);

/* error checking... */

bzBytesWritten = ((unsigned long) bzStream.total_out_hi32 << 32) + bzStream.total_out_lo32;
cumulativeBytesWritten += bzBytesWritten;

/* write compressed data in bzBuffer to standard output */
fwrite(bzBuffer, 1, bzBytesWritten, stdout);
fflush(stdout);
}
while (bzError == BZ_OK);
}
while (/* while there is a non-final myBuffer full of discrete chunks left to compress... */);

现在我们总结输出:
/* read in the final batch of bytes into myBuffer (with a total byte size of `myBufferLength`... */

/* compress remaining myBufferLength bytes in myBuffer */
bzStream.next_in = myBuffer;
bzStream.avail_in = myBufferLength;
bzStream.next_out = bzBuffer;
bzStream.avail_out = BZIP2_BUFFER_MAX_LENGTH;
do
{
bzStream.next_out = bzBuffer;
bzStream.avail_out = BZIP2_BUFFER_MAX_LENGTH;
bzError = BZ2_bzCompress(&bzStream, (bzStream.avail_in) ? BZ_RUN : BZ_FINISH);

/* bzError error checking... */

/* increment cumulativeBytesWritten by `bz_stream` struct `total_out_*` members */
bzBytesWritten = ((unsigned long) bzStream.total_out_hi32 << 32) + bzStream.total_out_lo32;
cumulativeBytesWritten += bzBytesWritten;

/* write compressed data in bzBuffer to standard output */
fwrite(bzBuffer, 1, bzBytesWritten, stdout);
fflush(stdout);
}
while (bzError != BZ_STREAM_END);

/* close stream */
bzError = BZ2_bzCompressEnd(&bzStream);

/* bzError checking... */

问题
  • 我在计算cumulativeBytesWritten (或者,特别是 bzBytesWritten )不正确,我该如何解决?

  • 我一直在调试版本中跟踪这些值,而且我似乎没有“重复计算” bzBytesWritten值(value)。该值被计数并使用一次以递增 cumulativeBytesWritten每次成功后 BZ2_bzCompress()经过。
  • 或者,我是不是不理解 bz_stream 的正确用法?州旗?

  • 例如,只要我继续发送一些字节,以下内容是否会压缩并保持 bzip2 流打开?
    bzError = BZ2_bzCompress(&bzStream, BZ_RUN);

    同样,以下语句是否可以压缩数据,只要至少有一些字节可以从 bzStream.next_in 访问指针( BZ_RUN ),然后当没有更多可用字节( BZ_FINISH )时流被包裹?
    bzError = BZ2_bzCompress(&bzStream, (bzStream.avail_in) ? BZ_RUN : BZ_FINISH);
  • 或者,我根本没有正确使用这些低级调用吗?我应该回到使用更高级别的调用来连续将一组压缩数据块附加到一个主文件吗?

  • 对此可能有一个简单的解决方案,但是在调试可能出现的问题的过程中,我已经将头撞在 table 上几天了,而且我没有取得太大进展。谢谢你的任何建议。

    最佳答案

    在回答我自己的问题时,我似乎错误计算了写入的字节数。我不应该使用 total_out_*成员。以下更正工作正常:

    bzBytesWritten = sizeof(bzBuffer) - bzStream.avail_out;

    其余计算如下。

    关于c - 使用 bzip2 低级例程压缩数据 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13065023/

    37 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com