【发布时间】:2010-10-12 06:30:33
【问题描述】:
我有一个由一些bzip2 档案组成的串联文件。我也知道该文件中单个 bzip2 块的大小。
我想从单个 bzip2 数据块中解压缩 bzip2 流,并将输出写入标准输出。
首先我使用fseek 将文件光标移动到所需的存档字节,然后将文件的“大小”-chunk 读入BZ2_bzRead 调用:
int headerSize = 1234;
int firstChunkSize = 123456;
FILE *fp = fopen("pathToConcatenatedFile", "r+b");
char *bzBuf = malloc(sizeof(char) * firstChunkSize);
int bzError, bzNBuf;
BZFILE *bzFp = BZ2_bzReadOpen(&bzError, *fp, 0, 0, NULL, 0);
# move cursor past header of known size, to the first bzip2 "chunk"
fseek(*fp, headerSize, SEEK_SET);
while (bzError != BZ_STREAM_END) {
# read the first chunk of known size, decompress it
bzNBuf = BZ2_bzRead(&bzError, bzFp, bzBuf, firstChunkSize);
fprintf(stdout, bzBuf);
}
BZ2_bzReadClose(&bzError, bzFp);
free(bzBuf);
fclose(fp);
问题是,当我将fprintf 语句的输出与在命令行上运行bzip2 的输出进行比较时,我得到了两个不同的答案。
具体来说,与在命令行上运行 bzip2 相比,我从这段代码中获得的输出更少。
更具体地说,此代码的输出是命令行进程输出的一个较小子集,我缺少感兴趣的 bzip2 块尾部的内容。
我通过另一种技术验证了命令行bzip2 提供了正确的答案,因此,我的C 代码的一些问题导致块末尾的输出丢失。我只是不知道那是什么问题。
如果您熟悉bzip2 或libbzip2,您能否就我在上面的代码示例中做错了什么提供任何建议?谢谢你的建议。
【问题讨论】:
-
文件中是否有任何 ASCII NUL 字节(零字节)?数据中是否有百分比字符?你使用
fprintf()非常危险——你可能应该使用fputs()甚至fwrite(),但如果做不到这一点,请使用fprintf(stdout, "%s", bzBuf);。 -
我得到与
fputs(bzBuf, stdout)或fprintf(stdout, "%s", bzBuf)相同的结果。据我所知,bzip2-ed 块是字母数字、换行符和制表符。生成bzip2块的输入中没有百分号或空字符,可以使用bzip2命令行工具成功解压缩 -
OK - 你在百分号上很幸运;零字节的缺失并不少见。您是否将 bzNBuf 中返回的字节数相加,以查看读取操作返回的内容是否与您在输出中获得的内容相加,或者 bzip2 在处理文件时获得的内容?您对“读取已知大小的第一个块”的评论具有误导性-无论如何,在它读取了一个块之后。你解压的文件是否比 firstChunkSize 大?
-
另外,您可能应该在
BZ2_bzRead()之后和fprintf()之前检查bzError。但是,与太少的数据相比,这更有可能最终得到额外的数据。 (你确定你的过程产生的结果比 bzip2 小吗?) -
无论我
fseek在我的连接文件中的哪个位置,我都会得到一个较小的结果。 API中的size参数是指正在读取的bzip2块的大小,还是未压缩输出的大小?从阅读 API 来看,这似乎是第一种选择,但我很可能是错的。
标签: c file-io compression bzip2