Zlib库对网页中deflate压缩数据的解压
来源:互联网 发布:unity3d计算机图形学 编辑:程序博客网 时间:2024/05/24 11:14
一般情况下网页请求的头里会有一个Content-Encoding字段来表示该网页启用了压缩算法来提高网页传输效率。一般情况下都是以Gzip或deflate为字段值,实际上是以deflate压缩算法来压缩的数据。工作中偶尔碰见了这样的页面内容没有一个解压的代码还挺麻烦的。
deflate 是最基础的算法,gzip在deflate的rawdata前增加了10个字节的 gzheader,尾部添加了8个字节的校验字节(可选 crc32 和 adler32) 和长度标识字节。
zlib库是一个C++常用的解压zip文件的库,提供了各种各样的接口以供调用。其中,deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比 inflateInit()多一个参数: -MAX_WBITS,表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节。使用inflateInit2时要求zlib库忽略zlib header。
zlib提供了很多接口,在这些复杂的操作之上封装了最简单的两个接口,compress和uncompress。我们一般直接调用就可以了。
简单介绍下常用的函数:
1、 deflateInit() + deflate() + deflateEnd()
3个函数结合使用完成压缩功能,具体用法看 example.c 的 test_deflate()函数. 其实 compress() 函数内部就是用这3个函数实现的(工程 zlib 的 compress.c 文件)
2、 inflateInit() + inflate() + inflateEnd()
和上面的类似,完成解压缩功能,uncompress()函数的内部实现使用的就是它们
3、uLong compressBound(uLong sourceLen);
计算需要的缓冲区长度,这个函数并不精确的计算压缩后的数据有多长,但是可以保证压缩后的长度不会这个结果还长,便于分配空间。
接下来就是我们最常用的一对函数
4、int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
压缩数据,要注意的是压缩后的BUF和大小是要预先分配好的,这也是我们为什么要使用compressBound这个函数的原因。
5、int uncompress (Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen);
解压缩数据,同样的,解压后的BUF大小要预先知道,太小了会解压失败。
一般情况下,compress和uncompress函数足以满足我们的要求。
最后附上解压一个从网页中获取的存有压缩数据的文件的代码:
/************************************************************************* > File Name: un_zip.cpp > Author:zeus > Mail:zuixuewosha@163.com > Created Time: 2017年06月09日 星期五 16时32分28秒 > useage: a.out src_file dst_file ************************************************************************/#include <stdlib.h>#include <stdio.h>#include <zlib.h>int main(int argc, char* argv[]){ FILE* file; unsigned char* src_buf = NULL; unsigned char* ubuf = NULL; int failed_number = 0; /* 通过命令行参数将srcfile文件的数据解压缩后存放到dstfile文件中 */ if(argc < 3) { printf("Usage: a.out srcfile dstfile\n"); return -1; } if((file = fopen(argv[1], "rb")) == NULL) { printf("Can\'t open %s!\n", argv[1]); return -1; } /* 装载源文件数据到缓冲区 */ fseek(file,0,SEEK_END); unsigned long src_length = ftell(file); unsigned long dst_length = 65536; rewind(file); printf("src_length is %d\n",src_length); if((src_buf = (unsigned char*)malloc(sizeof(unsigned char) * src_length)) == NULL) { printf("No enough memory!\n"); fclose(file); return -1; } fread(src_buf, sizeof(unsigned char), src_length, file); /* 解压缩数据,失败后分配更大的空间,最大失败次数 10 */ while(failed_number < 10) { if((ubuf = (unsigned char*)malloc(sizeof(unsigned char) * dst_length)) == NULL) { printf("No enough memory!\n"); fclose(file); return -1; } if(uncompress(ubuf, &dst_length, src_buf, src_length) != Z_OK) { printf("Uncompress %s failed,try allocate more space!\n", argv[1]); free(ubuf); ubuf = NULL; /*失败后分配两倍空间*/ dst_length *=2; failed_number++; } else { break; } } fclose(file); if((file = fopen(argv[2], "wb")) == NULL) { printf("Can\'t create %s!\n", argv[2]); return -1; } /* 保存解压缩后的数据到目标文件 */ fwrite(ubuf, sizeof(unsigned char), dst_length, file); fclose(file); free(src_buf); free(ubuf); return 0;}
- Zlib库对网页中deflate压缩数据的解压
- Delphi中获取IE网页后,对GZIP方式的网页解压(gzip,deflate)
- zlib对http中chunk数据解压
- zlib压缩解压库
- zlib压缩解压库
- web中gzip,deflate的压缩与解压
- 利用zlib库对HTTP收到的gzip数据解压
- 利用zlib库对HTTP收到的gzip数据解压
- zlib压缩库解压失败的问题
- 使用zlib实现gzip格式数据的压缩和解压
- 使用zlib实现gzip格式数据的压缩和解压
- [Qt]简单使用 Zlib 库压缩/解压数据
- 用zlib压缩与解压数据
- GZip、Deflate压缩算法对应的C#压缩解压函数
- 一个用zlib库写的解压和压缩程序
- 使用Zlib库进行文件的压缩和解压
- 使用Zlib库进行文件的压缩和解压
- zlib压缩和解压的使用
- nginx rewrite url 重写
- 2017.3CCCC团体程序设计天梯赛初赛总结
- CGI编程---登陆窗口
- 微信支付接口开发的安全规范
- 新版本JQuery中toggle被淘汰后的替代方法
- Zlib库对网页中deflate压缩数据的解压
- 浏览器兼容问题汇总
- 编程之美2.12 快速寻找满足条件的两个数
- 数据库中筛选两个字段都等于一的数据
- 8.8 精确4SAT问题证明
- C++算法学习——经典的抽象设计——基于栈实现的buffer
- 用Object获取sql语句返回结果
- jsp
- angularJS $q $http 与promise对象的关系