为了节省带宽许多网站都采用GZip压缩页面,Apache,PHP都能提供GZip支持,经GZip压缩的HTTP页面的HTTP头有如下标记:Content-Encoding = gzip
GZip数据以0x1f,0x8B开头,文件头长度通常为10。
用zlib的uncompress无法解成功,测试了网上许多版本都失败,最后总结了可行的代码:
int GZipUncompress(Byte *dest, uLong *destLen, Byte *src, uLong srcLen)
{
// 本文来源 外链网址已屏蔽www.okbase.net
int err;
z_stream d_stream;
memset(&d_stream, 0, sizeof(z_stream));
d_stream.next_in = src;
d_stream.avail_in = srcLen;
d_stream.next_out = dest;
d_stream.avail_out = *destLen;
err = inflateInit2(&d_stream, -MAX_WBITS);
if(err != Z_OK)
return(err);
d_stream.next_in += 10L; // 跳过GZip文件头,这里没有仔细处理,长度可以通过文件头数据取得
err = inflate(&d_stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&d_stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = d_stream.total_out;
err = inflateEnd(&d_stream);
return(err);
}
// 测试代码
char *pMem = ... // 数据源
int MemSize; // 数据源长度
unsigned long BufferSize = MemSize * 6;
char *pBuffer = new char[BufferSize]; // BufferSize要足够大
memset(pBuffer, 0, BufferSize);
int result = GZipUncompress((unsigned char *)pBuffer, &BufferSize, (unsigned char *)pMem, MemSize);
if(result == Z_OK)
{
// 成功
}
// 需要改进的几点问题
(1)没有处理目标缓冲区大小不够的情况
(2)跳过GZip文件头的长度没有从文件头中读取
时间不够,需要的朋友请自行修改,改好了记得贴一下自己的代码哦!