【发布时间】:2018-10-04 04:26:04
【问题描述】:
我正在尝试使用 zlib 压缩(压缩?)文本文件中的数据。 当我压缩文件时它似乎工作,但我试图预先 带有自定义标头的 zlib 压缩文件。文件和标题 应该压缩。但是,当我添加标题时, 压缩(放气)文件比预期的要短得多 输出为无效的 zlib 压缩对象。
代码运行良好,直到我在 XXX cmets 下面。
“FILE *source”变量是一个示例文件,我通常使用 /etc/passwd 并且“char *header”是“blob 2172\0”。 没有标头块,输出为 904 字节且可压缩 (可解压缩),但带有标头的只有 30 个字节。 它也作为一个无效的 zlib 对象出现,其标头块为 代码。
我犯错误的任何想法,特别是为什么输出是 标题无效且较短?
如果相关,我将在 FreeBSD 上写这篇文章。
#define Z_CHUNK16384
#define HEX_DIGEST_LENGTH 257
int
zcompress_and_header(FILE *source, char *header)
{
int ret, flush;
z_stream strm;
unsigned int have;
unsigned char in[Z_CHUNK];
unsigned char out[Z_CHUNK];
FILE *dest = stdout; // This is a temporary test
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, Z_BEST_SPEED);
//ret = deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, 15 | 16, 8,
Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
return ret;
/* XXX Beginning of writing the header */
strm.next_in = (unsigned char *) header;
strm.avail_in = strlen(header) + 1;
do {
strm.avail_out = Z_CHUNK;
strm.next_out = out;
if (deflate (& strm, Z_FINISH) < 0) {
fprintf(stderr, "returned a bad status of.\n");
exit(0);
}
have = Z_CHUNK - strm.avail_out;
fwrite(out, 1, have, stdout);
} while(strm.avail_out == 0);
/* XXX End of writing the header */
do {
strm.avail_in = fread(in, 1, Z_CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
do {
strm.avail_out = Z_CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush);
have = Z_CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while(strm.avail_out == 0);
} while (flush != Z_FINISH);
} // End of function
【问题讨论】:
-
一些问题,澄清一下:1)你定义了“#define Z_CHUNK16384”,我想它应该是“#define Z_CHUNK 16384”。如果 Z_CHUNK 在别处定义,程序会编译,但会使用意外的块大小。
-
2) 您在标头上使用 strlen。标头是空终止的字符串吗?
-
Z_CHUNK 被称为 CHUNK,在 zlib 文档的 zpipe.c 示例中定义为 16384。仅通过了解代码,我就知道标头不为空,但我认为您需要添加错误检查。
-
好的,我只是想指出,在第 1 行的#define 中的“Z_CHUNK”和“16384”之间应该有一个空格,否则你实际上并没有定义宏“Z_CHUNK” ,但“Z_CHUNK13384”。