[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的博 ...
随机推荐
- 使用TaskScheduler 调度器 实现跨线程的控件访问
//任务调度器 TaskScheduler UIscheduler = null; public Form1() { //获取任务调度器 UIscheduler = TaskScheduler.Fro ...
- Windows 7 任务栏图标消失(变透明,仍然占有地方,但是点击无反应)的解决方法
解决方案:清理资源管理器缓存(重启资源管理器) 1.打开程序管理器(ctrl+shift+esc) 2.在进程那里找到"explorer.exe",然后按结束进程 3.然后在文件( ...
- MySQL SELECT语句中只能输出1000行数据的原因
同事反映,客户的一套MySQL生产库,执行SELECT.. INTO OUTFILE语句只能导出1000行 最初以为是系统参数被重新设置了,建议他更改系统参数 mysql> set global ...
- 乘风破浪:LeetCode真题_038_Count and Say
乘风破浪:LeetCode真题_038_Count and Say 一.前言 这一道题目,很类似于小学的问题,但是如果硬是要将输入和结果产生数值上的联系就会产生混乱了,因此我们要打破思维定势. ...
- SQL Server:INFORMATION_SCHEMA.columns 与sys.columns 与 syscolumns对比
sys.columns视图 sys.columns是SQL Server从2005版本起引入的新的系统级视图.相关链接如下: Mapping SQL Server 2000 System Tables ...
- [python]python官方原版编码规范路径
1.进入python官方主页:https://www.python.org/ 2.按如下图进入PEP Index 3.选择第8个,即为python的规范
- css多种方法实现已知宽度和未知宽度的元素水平垂直居中
// html <div class="box-wrapper"> <div class="box"> 内部box <p>更 ...
- RxJS--Subject
Subject是Observable(可观察对象)的子类,subject是多播的,允许将值多播给多个observer(观察者),普通observable是单播. 每一个Subject都是一个Obser ...
- BZOJ3578:GTY的人类基因组计划2(集合hash,STL)
Description GTY召唤了n个人来做实验,GTY家的房子很大,有m个房间一开始所有人都在1号房间里,GTY会命令某人去某个房间等待做实验,或者命令一段区间的房间开始实验,实验会获得一些实验信 ...
- POJ3801 Crazy Circuits
嘟嘟嘟 上下界网络流之最小流. 建图不说啦,裸的. 在有附加源\(S\)和附加汇\(T\)的图上跑完后,删除和\(S, T\)相连的边.然后因为可能流多了,所以现在应该退流,于是我们从\(t\)到\( ...