当使用zlib时,当我尝试压缩13G的文件时,我对compress()
的调用给出Z_BUF_ERROR
,尽管我认为这是正确的缓冲区分配。此代码适用于较小的文件。
struct stat infile_stat;
FILE *fp = NULL;
if ((fp = fopen(md_of_name, "r")) == NULL) {
fprintf(stderr,
"Error: Unable to open file %s.\n",
md_of_name);
exit(1);
}
stat(md_of_name, &infile_stat);
size_t u_len = infile_stat.st_size;
char *u_buf = (char *)malloc(u_len);
if (u_buf == NULL) {
fprintf(stderr, "Error: Unable to malloc enough memory for the "
"uncompressed buffer\n");
exit(1);
}
if (fread(u_buf, 1, u_len, fp) < u_len) { // d
fprintf(stderr,
"Error: Unable to read in all of file %s. Exiting.\n ",
md_of_name);
exit(1);
}
fclose(fp);
size_t c_len = compressBound(u_len);
Bytef *c_buf = (Bytef *)malloc(c_len);
if (c_buf == NULL) {
fprintf(stderr, "Error: Unable to malloc enough memory for the "
"compressed BIM buffer\n");
exit(1);
}
fprintf(stderr, "u_len:%lu\tc_len:%lu\tc_buf:%p\n", u_len, c_len, c_buf);
int r = compress(c_buf, &c_len, (Bytef *)u_buf, u_len);
if (r == Z_MEM_ERROR)
fprintf(stderr, "Not enough memory\n");
else if (r == Z_BUF_ERROR)
fprintf(stderr, "Not enough room in the output buffer.\n");
assert(r == Z_OK);
当我在13922075353字节的文件上运行它时,输出为:
u_len:13922075353 c_len:13926324460 c_buf:0x7f2b82436010
Not enough room in the output buffer.
其次是断言失败。
更新
我认为这个错误是zlib中compress()
函数内部的转换问题的结果。如果我是正确的,则在zlib 1.2.8中的compress.c
的第40行返回错误
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.avail_out
变量设置在上面几行:
stream.avail_in = (uInt)sourceLen;
我相信演员是个问题。 sourceLen
是无符号长整数,当它被转换为uInt
位时被删除。在我的情况下,sourceLen
是13922075353,destLen
是13926324460(来自compressBound()
),但由于演员stream.avail_out
是1041422572.因此错误。
如果这是正确的,则缓冲区的大小存在隐式限制。我现在不明白的是为什么缓冲区大小是无符号长的。它们需要是无符号的整数。
答案 0 :(得分:0)
现在,我知道要查找的内容,我发现此问题是zlib FAQ中的地址,其中指出compress()
和uncompress()
可能限制为4GB,因为它们在一个电话。&#34;
我仍然认为压缩和解压缩不应该将大小视为无符号长。
答案 1 :(得分:0)
对于那些大的东西,您需要使用deflateInit()
,deflate()
和deflateEnd()
。