[Zlib]_[初级]_[使用zlib库压缩和解压STL string]
场景
1.一般在使用文本json传输数据, 数据量特别大时,传输的过程就特别耗时, 因为带宽或者socket的缓存是有限制的, 数据量越大, 传输时间就越长. 网站一般使用gzip来压缩成二进制.
说明
1.zlib库可以实现gzip和zip方式的压缩, 这里只介绍zip方式的二进制压缩, 压缩比还是比较可观的, 一般写客户端程序已足够.
2.修改了一下zpipe.c的实现, 其实就是把读文件改为读字符串, 写文件改为写字符串即可.
例子
// test_zlib.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <iostream>
#include <memory>
#include <assert.h>
#include "zlib.h"
// E:\software\Lib\compress\zlib-1.2.5\src\examples
// zpipe.c
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int CompressString(const char* in_str,size_t in_len,
std::string& out_str, int level)
{
if(!in_str)
return Z_DATA_ERROR;
int ret, flush;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
std::shared_ptr<z_stream> sp_strm(&strm,[](z_stream* strm){
(void)deflateEnd(strm);
});
const char* end = in_str+in_len;
size_t pos_index = 0;
size_t distance = 0;
/* compress until end of file */
do {
distance = end - in_str;
strm.avail_in = (distance>=CHUNK)?CHUNK:distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str+= strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if(ret == Z_STREAM_ERROR)
break;
have = CHUNK - strm.avail_out;
out_str.append((const char*)out,have);
} while (strm.avail_out == 0);
if(strm.avail_in != 0); /* all input will be used */
break;
/* done when last data in file processed */
} while (flush != Z_FINISH);
if(ret != Z_STREAM_END) /* stream will be complete */
return Z_STREAM_ERROR;
/* clean up and return */
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int DecompressString(const char* in_str,size_t in_len, std::string& out_str)
{
if(!in_str)
return Z_DATA_ERROR;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
std::shared_ptr<z_stream> sp_strm(&strm,[](z_stream* strm){
(void)inflateEnd(strm);
});
const char* end = in_str+in_len;
size_t pos_index = 0;
size_t distance = 0;
int flush = 0;
/* decompress until deflate stream ends or end of file */
do {
distance = end - in_str;
strm.avail_in = (distance>=CHUNK)?CHUNK:distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str+= strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if(ret == Z_STREAM_ERROR) /* state not clobbered */
break;
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
have = CHUNK - strm.avail_out;
out_str.append((const char*)out,have);
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (flush != Z_FINISH);
/* clean up and return */
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
int _tmain(int argc, _TCHAR* argv[])
{
const char* buf = "01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"qwertyuiop[]";
std::cout << "========= CompressString ===========" << std::endl;
std::cout << "Source Buffer Size: " << strlen(buf) << std::endl;
std::string out_compress;
assert(CompressString(buf,strlen(buf),out_compress,Z_DEFAULT_COMPRESSION) == Z_OK);
std::cout << "Compress Buffer Size: " << out_compress.size() << std::endl;
std::cout << "========= DecompressString ===========" << std::endl;
std::string out_decompress;
assert(DecompressString(out_compress.c_str(),out_compress.size(),out_decompress) == Z_OK);
std::cout << "Decompress Buffer Size: " << out_decompress.size() << std::endl;
assert(!out_decompress.compare(buf));
return 0;
}
输出:
========= CompressString ===========
Source Buffer Size: 662
Compress Buffer Size: 38
========= DecompressString ===========
Decompress Buffer Size: 662
参考
[Zlib]_[初级]_[使用zlib库压缩和解压STL string]的更多相关文章
- C#文件或文件夹压缩和解压方法(通过ICSharpCode.SharpZipLib.dll)
我在网上收集一下文件的压缩和解压的方法,是通过ICSharpCode.SharpZipLib.dll 来实现的 一.介绍的目录 第一步:下载压缩和解压的 ICSharpCode.SharpZipLib ...
- 黄聪:.NET中zip的压缩和解压——SharpCompress
使用Packaging无法实现通用的zip(使用其他工具压缩)的解压,只支持通过Packaging压缩包zip的解压,而SharpZipLib是基于“GPL”开源方式,风险比较大.在codeplex找 ...
- [Swift通天遁地]七、数据与安全-(9)文件的压缩和解压
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- C#压缩和解压文件
这里用两种方法实现C#压缩和解压文件 1.使用System.IO.Compression名称空间下的相关类(需引用 System.IO.Compression.FileSystem和System.IO ...
- 【C#公共帮助类】WinRarHelper帮助类,实现文件或文件夹压缩和解压,实战干货
关于本文档的说明 本文档使用WinRAR方式来进行简单的压缩和解压动作,纯干货,实际项目这种压缩方式用的少一点,一般我会使用第三方的压缩dll来实现,就如同我上一个压缩类博客,压缩的是zip文件htt ...
- java 文件压缩和解压(ZipInputStream, ZipOutputStream)
最近在看java se 的IO 部分 , 看到 java 的文件的压缩和解压比较有意思,主要用到了两个IO流-ZipInputStream, ZipOutputStream,不仅可以对文件进行压缩,还 ...
- C#实现通过Gzip来对数据进行压缩和解压
C#实现通过Gzip来对数据进行压缩和解压 internal static byte[] Compress(byte[] data) { using (var compressedStream = n ...
- linux常用命令:4文件压缩和解压命令
文件压缩和解压命令 压缩命令:gzip.tar[-czf].zip.bzip2 解压缩命令:gunzip.tar[-xzf].unzip.bunzip2 1. 命令名称:gzip 命令英文原意:GNU ...
- .net文件压缩和解压及中文文件夹名称乱码问题
/**************************注释区域内为引用http://www.cnblogs.com/zhaozhan/archive/2012/05/28/2520701.html的博 ...
随机推荐
- qtcreator minggw 支持c++11
pro文件添加 QMAKE_CXXFLAGS += -std=c++11
- JavaScript语法详解:运算符和表达式
本文首发于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 我们在上一篇文章里讲到了JS中变量的概念,本篇文章讲一下运算符和表达式. 比 ...
- NodeJS链接MySql数据库
//1.用npm命令安装mysql模块 npm install mysql //2.js文件中引入mysql模块 const mysqlModule = require('mysql'); //3.创 ...
- mysql中InnoDB表为什么要建议用自增列做主键
InnoDB引擎表的特点 1.InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 (图片来源于网上) B+ 树的特点: (1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关 ...
- SmartUpload相关类的说明
㈠ File类 这个类包装了一个上传文件的所有信息.通过它,可以得到上传文件的文件名.文件大小.扩展名.文件数据等信息. File类主要提供以下方法: 1.saveAs作用:将文件换名另存. 原型: ...
- [python] 统计某一路径下所有代码真实行数(空行已被过滤)
#-*- coding:utf-8 -*- ''' Created on 2018年8月15日 @author: anyd ''' import os list_line = [] filepat ...
- flexible.js结合rem实现移动端自适应布局
1. 配置开发工具(sublime)插件 https://github.com/flashlizi/cssrem 注意: 只有在‘.css’后缀文件才能使用此插件功能 2. 在h ...
- 遇到 ORACLE 错误 1658
在对oracle导入数据时,多次报以下错误: IMP-00003: 遇到 ORACLE 错误 1659ORA-01659: 无法分配超出 1 的 MINEXTENTS (在表空间 ZSTA_DATA_ ...
- Python datetime.md
datetime datetime模块包含了一些用于时间解析.格式化.计算的函数. Times 时间值由time类来表示, Times有小时, 分, 秒和微秒属性. 以及包含时区信息. 初始化time ...
- python第二十九课——文件读写(读取数据操作)
演示读取数据操作:path=r'a.txt' 1.打开文件f1=open(path,'r') 2.读取数据content1=f1.read(3)print(content1) content1=f1. ...