我在使用 zlib 膨胀一个简单的 HTML 文件时遇到了一些问题,该文件已使用 gzip 压缩。
该文件以及我打开它的步骤以及我尝试使用的通货膨胀函数在下面。当我运行该函数时,我得到 zlib 的错误代码Z_DATA_ERROR。据我所知,我已经忠实地坚持了 zlib 的使用示例(在此处找到),但尽管如此,我还是遇到了一些麻烦。
膨胀例程直到调用 inflate() 方法并且函数在 switch 语句中返回后才会出现错误,但我无法追踪问题所在。
这里的任何帮助将不胜感激。
压缩文件:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST</title>
</head>
<body>
<ul>
<li>hello</li>
<li>I</li>
<li>am</li>
<li>a</li>
<li>test</li>
<li>web</li>
<li>page</li>
</ul>
</body>
</html>
注意:这些是gzip压缩之前的文件内容。
文件打开:源文件在这里然后传入 inf()。
FILE *sourcefile;
sourcefile = fopen("/Users/me/pathtofile/test.html.gz", "r");
充气程序:
inf(FILE *source, FILE *dest){
int chunk = 16384;
//setup zlib variables
int return_val;
unsigned have;
z_stream z_strm;
unsigned char in[chunk];
unsigned char out[chunk];
//allocate inflate state
z_strm.zalloc = Z_NULL;
z_strm.zfree = Z_NULL;
z_strm.opaque = Z_NULL;
z_strm.avail_in = 0;
z_strm.next_in = Z_NULL;
return_val = inflateInit(&z_strm);
if(return_val != Z_OK){
return return_val;
}
cout << "zlib setup complete" << endl;
//decompress
do{
z_strm.avail_in = fread(in, 1, chunk, source);
//check for error
if (ferror(source)){
(void)inflateEnd(&z_strm);
return Z_ERRNO;
}
if(z_strm.avail_in == 0){
break;
}
z_strm.next_in = in;
cout << "inflate loop") << endl;
//inflate the data
do{
z_strm.avail_out = chunk;
z_strm.next_out = out;
return_val = inflate(&z_strm, Z_NO_FLUSH);
assert(return_val != Z_STREAM_ERROR);
cout << "switch statement start" << endl;
switch(return_val){
case Z_NEED_DICT:
return_val = Z_DATA_ERROR;
cout << "case: Z_NEED_DICT" << endl;
case Z_DATA_ERROR:
cout<< "case: Z_DATA_ERROR" << endl;
case Z_MEM_ERROR:
cout << "case: Z_MEM_ERROR" << endl;
void(inflateEnd(&z_strm));
return return_val;
}
cout << "switch statement end" << endl;
have = chunk - z_strm.avail_out;
if(fwrite(out, 1, have, dest) != have || ferror(dest)){
(void)inflateEnd(&z_strm);
return Z_ERRNO;
}
}while(z_strm.avail_out == 0);
}while(return_val != Z_STREAM_END);
}
使用 inflateInit2()
而不是 inflateInit()
来请求解码 gzip 格式。 默认情况下,zlib 正在寻找 zlib 格式。
主要原因可能是您的初始化错误 inflateInit2(&z_strm,15+32)
和充气 inflate(&z_strm, Z_SYNC_FLUSH );
可以解决你的问题。