我尝试使用 zlib 来检测压缩 gz 数据流的结尾。 我不需要未压缩的内容,我的目标是获取指向流的开头和结尾的指针。 我的代码适用于小文件,但适用于大文件。尝试为 outbuf 分配更多内存,但没有成功。 主要是从zlib的例子复制粘贴过来的,有什么问题吗?
// fopen(filename,"rb")...fread(inbuf, inlen, 1, fd);
int gzip_dctest(unsigned char *inbuf, unsigned int inlen) {
unsigned int outlen = 262144;
unsigned char *outbuf = malloc(outlen);
int ret = 0;
z_stream infstream;
/* allocate inflate state */
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = 0;
infstream.next_in = Z_NULL;
ret = inflateInit2(&infstream, MAX_WBITS | 32); // gzip/zlib header autodetect
if (ret != Z_OK) {
fprintf(stderr, "gzip_test: init fail (%d: %s)\n", ret, infstream.msg);
return ret;
}
unsigned int ptr = 0;
/* decompress until deflate stream ends or end of file */
do {
infstream.next_in = inbuf + ptr;
infstream.avail_in = inlen - ptr;
if (infstream.avail_in > (outlen / 8)) infstream.avail_in = (outlen / 8); // get chunk size
if (infstream.avail_in == 0)
break;
/* run inflate() on input until output buffer not full */
do {
ptr += infstream.avail_in;
infstream.avail_out = outlen;
infstream.next_out = outbuf;
ret = inflate(&infstream, Z_NO_FLUSH);
if (ret < 0) {
fprintf(stderr, "gzip_test: inflate fail at %u (%d: %s)\n", ptr - infstream.avail_in, ret, infstream.msg);
return ret;
}
} while (infstream.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
inflateEnd(&infstream);
return ptr - infstream.avail_in;
}
问题文件的示例输出(403709952 未压缩,99152355 压缩大小):
gzip_test: inflate fail at 2374700 (-3: invalid code lengths set)
此文件上的“gzip -d”没有给出错误。 “1.cpio.gz:75.4%——替换为1.cpio” 如果我再次压缩它(gzip 命令),我的代码中会出现另一个错误:
gzip_test: inflate fail at 2381863 (-3: invalid block type)
期望任何文件大小的工作代码。
您的
ptr += infstream.avail_in;
需要移到内部 do
循环之外。然后就可以正常使用了。
您还需要在返回之前添加
free(outbuf);
,无论是错误还是成功。