zlib 不同解压大小
zlib different decompresssion size
我正在尝试使用 zlib 进行解压。我查看了 zlib 站点上的一个教程,并且 inflate 代码产生了不同大小的输出。
int CZLib::Inflate() {
int ret;
unsigned int have;
z_stream zstream;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zstream.avail_in = 0;
zstream.next_in = Z_NULL;
ret = inflateInit(&zstream);
if (ret != Z_OK)
return ret;
do {
zstream.avail_in = fread(in, 1, CHUNK, fin);
if (ferror(fin)) {
(void)inflateEnd(&zstream);
return Z_ERRNO;
}
if (zstream.avail_in == 0) break;
zstream.next_in = in;
do {
zstream.avail_out = CHUNK;
zstream.next_out = out;
ret = inflate(&zstream, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&zstream);
return ret;
}
have = CHUNK - zstream.avail_out;
if (fwrite(out, 1, have, fout) != have || ferror(fout)) {
(void)inflateEnd(&zstream);
return Z_ERRNO;
}
} while (zstream.avail_out == 0);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&zstream);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
和其他
int CZLib::Inflate(const std::string& src) {
std::vector<char> output;
z_stream zstream;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zstream.avail_in = 0;
zstream.next_in = Z_NULL;
int ret = inflateInit(&zstream);
if (ret != Z_OK)
return ret;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
int have = 0, nByte = CHUNK, off = 0, remaining = src.size();
if (src.size() < CHUNK) nByte = src.size();
do {
memcpy(in, &src[off], nByte);
off += nByte;
remaining -= nByte;
if (nByte > 0) zstream.avail_in = nByte;
if (remaining > CHUNK) { nByte = CHUNK; }
else { nByte = remaining; }
if (zstream.avail_in == 0) break;
zstream.next_in = in;
do {
zstream.avail_out = CHUNK;
zstream.next_out = out;
ret = inflate(&zstream, Z_NO_FLUSH);
have = CHUNK - zstream.avail_out;
output.insert(output.end(), out, out + have);
} while (zstream.avail_out == 0);
} while (ret != Z_STREAM_END);
CFile* file = new CFile("in.out", "wb");
file->Write<char>(&output[0], output.size());
delete file;
return ret;
}
它使用相同的数据。其中一个读取磁盘上的文件,另一个使用内存(缓冲方法)。 CHUNK 大小 16384。第一个代码产生 524288(0x80000) 和其他 524800 (0x80200) 字节。差异是 512 字节。为什么会这样?
在第一个代码示例中有这一行
zstream.avail_in = fread(in, 1, CHUNK, fin);
然后你有
if (zstream.avail_in == 0) break;
停止循环。
在第二个代码示例中,您有相同的行来停止循环,但您还有这一行:
if (nByte > 0) zstream.avail_in = nByte;
^^^^^^^^^
So you only assign to zstream.avail_in when nByte > 0
....
....
if (zstream.avail_in == 0) break;
^^^^^^^^^^^^^^^^
Consequently this will not be true when nByte is zero and the
code will not exit
试试这个:
zstream.avail_in = nByte; // Unconditional assignment
....
if (zstream.avail_in <= 0) break; // Less or equal to zero
我正在尝试使用 zlib 进行解压。我查看了 zlib 站点上的一个教程,并且 inflate 代码产生了不同大小的输出。
int CZLib::Inflate() {
int ret;
unsigned int have;
z_stream zstream;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zstream.avail_in = 0;
zstream.next_in = Z_NULL;
ret = inflateInit(&zstream);
if (ret != Z_OK)
return ret;
do {
zstream.avail_in = fread(in, 1, CHUNK, fin);
if (ferror(fin)) {
(void)inflateEnd(&zstream);
return Z_ERRNO;
}
if (zstream.avail_in == 0) break;
zstream.next_in = in;
do {
zstream.avail_out = CHUNK;
zstream.next_out = out;
ret = inflate(&zstream, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&zstream);
return ret;
}
have = CHUNK - zstream.avail_out;
if (fwrite(out, 1, have, fout) != have || ferror(fout)) {
(void)inflateEnd(&zstream);
return Z_ERRNO;
}
} while (zstream.avail_out == 0);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&zstream);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
和其他
int CZLib::Inflate(const std::string& src) {
std::vector<char> output;
z_stream zstream;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zstream.avail_in = 0;
zstream.next_in = Z_NULL;
int ret = inflateInit(&zstream);
if (ret != Z_OK)
return ret;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
int have = 0, nByte = CHUNK, off = 0, remaining = src.size();
if (src.size() < CHUNK) nByte = src.size();
do {
memcpy(in, &src[off], nByte);
off += nByte;
remaining -= nByte;
if (nByte > 0) zstream.avail_in = nByte;
if (remaining > CHUNK) { nByte = CHUNK; }
else { nByte = remaining; }
if (zstream.avail_in == 0) break;
zstream.next_in = in;
do {
zstream.avail_out = CHUNK;
zstream.next_out = out;
ret = inflate(&zstream, Z_NO_FLUSH);
have = CHUNK - zstream.avail_out;
output.insert(output.end(), out, out + have);
} while (zstream.avail_out == 0);
} while (ret != Z_STREAM_END);
CFile* file = new CFile("in.out", "wb");
file->Write<char>(&output[0], output.size());
delete file;
return ret;
}
它使用相同的数据。其中一个读取磁盘上的文件,另一个使用内存(缓冲方法)。 CHUNK 大小 16384。第一个代码产生 524288(0x80000) 和其他 524800 (0x80200) 字节。差异是 512 字节。为什么会这样?
在第一个代码示例中有这一行
zstream.avail_in = fread(in, 1, CHUNK, fin);
然后你有
if (zstream.avail_in == 0) break;
停止循环。
在第二个代码示例中,您有相同的行来停止循环,但您还有这一行:
if (nByte > 0) zstream.avail_in = nByte;
^^^^^^^^^
So you only assign to zstream.avail_in when nByte > 0
....
....
if (zstream.avail_in == 0) break;
^^^^^^^^^^^^^^^^
Consequently this will not be true when nByte is zero and the
code will not exit
试试这个:
zstream.avail_in = nByte; // Unconditional assignment
....
if (zstream.avail_in <= 0) break; // Less or equal to zero