先上源码

参数说名:

- 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. Broken 2020: 1 靶机

    这个靶机的作者脑洞太大了 扫描下端口,就普通的ssh http服务 扫描下目录,发现了一个2个cms目录 进来cms发现是个安装界面,但是后面安装失败,无意返回cms发现出现了一个flag 进入/cm ...

  2. Linux expect用法介绍

    1.expect是linux中一个交互命令,一般在 /usr/bin/expect路径下,如果该路径未加入到环境中需要先添加,其作用场景常用于交互执行输入指令 常用命令: expect 获取上一命令执 ...

  3. 神经网络实现fashion数据集

    import tensorflow as tf import numpy as np fashion=tf.keras.datasets.fashion_mnist (x_train,y_train) ...

  4. Revit二次开发——非模态窗口的事件处理

    一.起因    自己在写revit二开时,有一个Winform窗体按钮点击事件需要 触发调用事务进行处理,结果出现“异常“Starting a transaction from an external ...

  5. Redis设计与实现——数据结构与对象

    SDS 简单动态字符串 在redis数据库里面,包含字符串值得键值对在底层都是由SDS实现的. redis >  set msg "hello world" 1)键值对的键是 ...

  6. Python Matplotlib绘图基础

    Matplotlib绘图基础 1.Figure和Subplot import numpy as np import matplotlib.pyplot as plt #创建一个Figure fig = ...

  7. Ubutun重启网卡

    一.network利用root帐户# service networking restart 或者/etc/init.d/networking restart 二.ifdown/ifup# ifdown ...

  8. 文华财经赢顺外盘期货行情数据API接口开放代码

    文华财经赢顺外盘期货行情数据API接口开放代码        怎么才能获取到外盘期货行情数据API接口呢?不少朋友就会考虑到文华财经行情API接口,本身文华财经就是一个软件提供商,提供行情API接口也 ...

  9. 解决使用git,ssh每次都要输入密码

    建议:生成ssh 公钥私钥的时候,不要输入密码. 解决方案: 1.修改密码:使用命令 ssh-keygen -p 然后修改密码的时候直接回车,也就是把密码置空. 2.重新生成ssh key, 用 ss ...

  10. Reinforcement learning in populations of spiking neurons

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 尽管存在神经元变异性,但是群体编码被广泛认为是实现可靠行为响应的重要机制.但是,随着全局奖励信号与任何单独神经元的性能越 ...