为什么 zlib 放气初始化调用一次不起作用?
why zlib deflateInit calling once not working?
我目前正在编写一个使用 zlib 压缩字符数组的函数。由于我想优化性能和速度,我只想调用 deflateInit(( 一次并重用 zstream 对象,因为我想避免重新分配,反复取消分配。我已经尝试了下面的方法,它只是更新 zstream 对象中的输入和输出缓冲区,但它没有从 while 循环的第二次迭代中给出正确的输出。下面是代码:
#include <stdio.h>
#include <iostream>
#include <string.h> // for strlen
#include <assert.h>
#include <chrono>
#include "zlib.h"
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c
int main(int argc, char * argv[]) {
// original string len = 36
char a[500] = {};
for (int i = 0; i < 498; i++) {
a[i] = 'a';
}
a[499] = ' ';
// placeholder for the compressed (deflated) version of "a"
char b[500] = {};
// placeholder for the UNcompressed (inflated) version of "b"
char c[500] = {};
printf("Uncompressed size is: %lun", strlen(a));
printf("Uncompressed string is: %sn", a);
printf("n----------nn");
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
deflateInit( & defstream, Z_BEST_COMPRESSION);
int i = 0;
while (i < 5) {
auto t1 = std::chrono::high_resolution_clock::now();
// setup "a" as the input and "b" as the compressed output
// STEP 1.
// deflate a into b. (that is, compress a into b)
// zlib struct
int ret;
char b[500] = {};
defstream.avail_in = (uInt) strlen(a) + 1; // size of input, string + terminator
defstream.next_in = (Bytef * ) a; // input char array
defstream.avail_out = 500;
defstream.next_out = (Bytef * ) b;
ret = deflate( & defstream, Z_FINISH); /* no bad return value */
std::cout << "ret" << ret << std::endl;
std::cout << "avail_out" << defstream.avail_out << std::endl;
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
// This is one way of getting the size of the output
printf("Compressed size is: %lun", strlen(b));
printf("Compressed string is: %sn", b);
std::cout << "Compressed return value is: " << ret << std::endl;
std::cout << "Avail out is: " << defstream.avail_out << std::endl;
std::cout << "Compressed length is: " << defstream.total_out << std::endl;
printf("n----------nn");
memset(b, 0, 500);
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << "Timestamp: Total compression took: " <<
std::chrono::duration_cast < std::chrono::microseconds > (t2 - t1).count() <<
" microsecondsn";
i++;
}
deflateEnd( & defstream);
// inflateEnd(&infstream);
return 0;
}
输出:
----------
ret1
avail_out35
Compressed size is: 9
Compressed string is: x�KL#
0
Compressed return value is: 1
Avail out is: 35
Compressed length is: 15
----------
Timestamp: Total compression took: 103 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is:
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15
----------
Timestamp: Total compression took: 42 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is:
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15
----------
Timestamp: Total compression took: 41 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is:
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15
----------
Timestamp: Total compression took: 41 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is:
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15
----------
Timestamp: Total compression took: 42 microseconds
在这里你可以看到,我从 while 循环的第二次迭代中得到错误代码 -5 (Z_BUF_ERROR( 和空 b 数组。但是如果我在 while 循环中移动 zlib 对象声明和 deflateInit((,一切正常。有什么解释吗?
在 zlib 的文档中,他们写道:
如果参数 flush 设置为 Z_FINISH,则处理挂起的输入,刷新挂起的输出,如果有足够的输出空间,则 Calm 返回带有 Z_STREAM_END 的压缩。如果 deflate 返回 Z_OK 或 Z_BUF_ERROR,则必须再次调用此函数,并具有 Z_FINISH 和更多的输出空间(avail_out 年更新(,但没有更多的输入数据,直到它返回并显示Z_STREAM_END或错误。放气返回Z_STREAM_END后,流上唯一可能的操作是放气重置或放气结束。
所以它需要更多的缓冲区,注意你的缓冲区是 500,但只说可用是 50,这可能是错误,否则你需要更多逻辑来添加更多缓冲区。
相关文章:
- 为什么 zlib 放气初始化调用一次不起作用?
- (C++)虽然循环一次不起作用,但我引入了多个变量
- 注释一行使代码工作,而没有它,代码不起作用
- 比较字符串的 GetLine 工作一次,然后比较之后不起作用
- 布尔函数在一段时间内不起作用
- 将列表元素移动到列表末尾的函数多次不起作用
- 为什么我的Glreadpixels程序在另一台计算机中不起作用
- 我正在上一门课程,但讲师说的东西不起作用
- gets() 在第一次循环迭代中不起作用,但在后续迭代中工作
- C++:一次阅读一个字符,直到一行的末尾不起作用
- 两种不同的解分配向量的方法为什么一种不起作用?
- QWebPage在第一次加载后不起作用
- 将消息发布到隐藏表单第一次不起作用
- 在 Mac 中将一维数组转换为二维不起作用
- 在循环重复两次之前,break 语句不起作用
- getline() 在 while 循环中第二次不起作用
- 为什么 SearchBack 中的 if (find == A[i]) 除了第一次之外没有给出 true?在调试时,除了第一次之外显然不起作用
- 功能删除在我第二次激活它时不起作用
- 如果其他以及 >=(2 次)编译良好但不起作用
- 为什么我的程序在另一台计算机上不起作用?