先上源码

参数说名:

- source :gzip格式流内容。

- len: gzip流长度

- dest: 解压后字符流指针

- gzip: 压缩标志,非0时解压gzip格式,否则按照zip解压

说明:代码经过测试。解压后内容printf或者cout出来是乱码的,保存为文件是可以的,如果文件还是乱码,以utf-8打开就能正常显示(Windows默认Ansi编码,编码区别自己百度)。

#ifndef __GUNZIP_H__
#define __GUNZIP_H__ #include "zlib.h"
#include "stdlib.h"
#include "string.h"
#define CHUNK 64 int inflate_read(unsigned char *source, int len, unsigned char **dest, int gzip)
{
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int totalsize = 0; /* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL; if(gzip)
ret = inflateInit2(&strm, 47);
else
ret = inflateInit(&strm); if (ret != Z_OK)
return ret; strm.avail_in = len;
strm.next_in = source; /* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
//assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return ret;
} have = CHUNK - strm.avail_out;
totalsize += have;
*dest = (unsigned char*)realloc(*dest,totalsize);
memcpy(*dest + totalsize - have, out, have);
} while (strm.avail_out == 0); /* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
#endif

说明:上树源码并不验证文件内容完整性。

编译需要zlib库支持,连接选项’-lz’,如果提示错误安装zlib1g, zlib1g-dev.

解压网页

现在网站为了减小带宽占用,会对传输内容做压缩。nginx就默认开启gzip压缩。通过浏览器(火狐,chrome)f12可以查看当前页面传输格式。’Content-Encoding’ 头域指明文件的压缩算法;’Content-Length’指明传输文件的长度;’Transfer-Encoding’指明传输形式,如图中的‘chunked’表示块传输(具体自己百度)。其中’Content-Length’与’Transfer-Encoding’是一对矛盾的存在,而这只能有其一。块传输允许服务器再不知道要回应多少内容时候先传输一部分,在结束时候明显标记技术。



网站会根据客户端的请求决定是否对内容进行压缩,浏览器HTTP请求头有’Accept-Encoding’ 头域指定可以接受的内容形式。

步骤

  1. 解压缩网页需要判断压缩内容开始的位置,压缩内容开始是在http头部结束位置,HTTP协议规定HTTP头域每一个标签结束需要以’\r\n’结束,在头结束位置以’\r\n’与内容分割。也就是http头结束是’\r\n\r\n’,在这之后就是压缩内容。
  2. gzip格式是以’0x1f 0x8b’开始的。
  3. 文件长度:如果未采取块传输,HTTP 响应的 ‘Content-Length’就是压缩内容的长度。如果采取块传输需要缓存每一部分,直到结束。因为压缩不是按块压缩的,而是分块传输的gzip实体。

最后建议:如果采用本代码进行解压网页,不是很建议,自己需要做的工作比较多,需要缓存,重组,解压。有另一种简单方式是利用’libcurl’,libcurl 支持自解压,只需要设置 CURLOPT_ENCODING 选项。


解压gzip格式文件(包括网页)的更多相关文章

  1. Linux 解压xz格式文件及安装xz

    1.安装xz命令 # yum install epel-release -y # yum install xz -y 2.将xz文件解压为tar文件 # xz -d test.tar.xz 3.将ta ...

  2. Linux下批量解压.Z格式文件

    下面的代码演示如何将当前目录下sj目录下的所有.Z格式文件解压到sj_result目录下. 代码示例: for file in `ls ./sj` do prefix=${file%.*} echo ...

  3. mac解压7z格式文件

    brew直接安装解压工具 $ brew search 7z p7zip $ brew install p7zip ==> Downloading https://downloads.source ...

  4. 解压tar.gz文件报错gzip: stdin: not in gzip format解决方法

    解压tar.gz文件报错gzip: stdin: not in gzip format解决方法 在解压tar.gz文件的时候报错 1 2 3 4 5 [Sun@localhost Downloads] ...

  5. 使用commons-compress解压GBK格式winzip文件到UTF8,以及错误使用ZipArchiveInputStream读出来数据全是空的解决办法

    先上正确方法: 正确方式应该为,先创建一个ZipFile,然后对其entries做遍历,每一个entry其实就是一个文件或者文件夹,检测到文件夹的时候创建文件夹,其他情况创建文件,其中使用zipFil ...

  6. Linux中下载、解压、安装文件

    一.将解压包发送到linux服务器上: 1.在windos上下载好压缩包文件后,通过winscp等SFTP客户端传送给linux 2.在linux中通过wget命令直接下载 #wget [选项] [下 ...

  7. Linux中下载、解压、安装文件(转)

    原文地址:http://www.cnblogs.com/red-code/p/5539399.html 一.将解压包发送到linux服务器上: 1.在windos上下载好压缩包文件后,通过winscp ...

  8. 【VC++技术杂谈008】使用zlib解压zip压缩文件

    最近因为项目的需要,要对zip压缩文件进行批量解压.在网上查阅了相关的资料后,最终使用zlib开源库实现了该功能.本文将对zlib开源库进行简单介绍,并给出一个使用zlib开源库对zip压缩文件进行解 ...

  9. [Linux] 解压tar.gz文件,解压部分文件

    遇到数据库无法查找问题原因,只能找日志,查找日志的时候发现老的日志都被压缩了,只能尝试解压了   数据量比较大,只能在生产解压了,再进行查找 文件名为*.tar.gz,自己博客以前记录过解压方法: h ...

随机推荐

  1. 阿里云日志服务SLS

    前言: 刚入职实习了几天,我发现我的任务就是学习阿里云日志服务这块业务内容,这个功能和mysql一样,但是速度和视觉却是甩mysql这类数据库几条街. 当得知公司没人会这项技术后(在这之前我也没听过, ...

  2. 7、TypeScript类型、接口、类、泛型综合使用 -- TypeScript封装统一操作Mysql Mongodb Mssql的底层类库。

    功能:定义一个操作数据库的库,支持Mysql Mssql Mongodb 要求:Mysql Mssql Mongodb功能一样 都有add.update.delete.get方法 注意:约束统一的规范 ...

  3. 什么是servlet(转)

    一.什么是servlet? 处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西.理解这个的前提是了解一些http协议的东西,并且知道 ...

  4. JavaScript学习系列博客_18_JavaScript中的匿名函数

    匿名函数 - 用函数声明的方式创建一个函数时,不加函数名称. function sum(){ console.log("我是函数sum")} - 不加名称,这样写浏览器是会报错的. ...

  5. [PyTorch 学习笔记] 1.4 计算图与动态图机制

    本章代码:https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson1/computational_graph.py 计算图 深 ...

  6. SCAFFOLD: Stochastic Controlled Averaging for On-Device Federated Learning

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 以下是对本文关键部分的摘抄翻译,详情请参见原文. arXiv:1910.06378v1 [cs.LG] 14 Oct 2019 Abstr ...

  7. C++ strcmp与strncmp的比较

    C++ strcmp与strncmp的比较(转载)  原文链接:https://www.cnblogs.com/ybqjymy/p/12565444.html strcmp与strncmp都是用来比较 ...

  8. 聊一聊RocketMQ的注册中心NameServer

    前言 上次我们一起了解了RocketMQ的基本架构原理,那简单的回顾一下RocketMQ的架构组成. RocketMQ其实包含了四个核心部分,NameServer.Broker.Producer.Co ...

  9. Single Shot MultiBox Detector论文翻译【修改】

    这几天读了SSD论文的原理部分,看了别人的翻译,发现很多应该都是google直接翻译过来的,有些地方读的不是很通顺,自己就在自己的理解和搜索的基础上对我看的那篇翻译做了一些修改.[原文地址:http: ...

  10. 0827考试 T1

    Description ​ 有一棵树,每个点有一个权值,找到一个权值最大的"乙烷"模型. ​ "乙烷"模型是指: ​ 其中黑点表示可以有0个或多个点. Samp ...