C++zlib库实现的GZIP压缩解压缩工具类【多图警告^_^】
前几天和服务端同事联调TCP传输压缩后的Json串,遇到了 GZIP压缩问题。
需要把原来使用的的压缩算法和后端统一,现在来总结一下。
【注意】 这里就以Windows的Debug环境为例,Release版也是一样,只需更改配置编译就好。
代码演示中不未涉及文件序列化问题。文件(文件夹)压缩问题,可以参考zip压缩文章Zip压缩解压缩
1.下载zlib源码及工程文件:
https://www.zlib.net/
2.拿到源码包解压看看
3.打开目录zlib-1.2.11\contrib\vstudio\vc12下的解决方案:
一堆错误,编译失败:
解决方案:https://www.cnblogs.com/lzhu/p/9602674.html
我在示例中使用的VS2013编译的VC12的示例解决方案,报错。得把这六个工程都修复下:
编译成功:
4.编译成功,得到库文件:
打开工程目录,从x86\ZlibDllDebug下拿到库文件zlibwapi.lib和zlibwapi.dll,再从压缩包根目录zlib-1.2.11\下拿到zlib.h、zconf.h、zutil.h三个头文件
5.新建测试工程,并添加zlib目录,把拿到的lib文件以及三个头文件文件放进去,并把dll文件放到debug目录下。
6.demo工程属性-链接器-常规-附加依赖项-…/zlib/debug/zlibwapi.lib;
7.添加工具类CGZipAssistant到工程里面:
/*
GZipAssisant.h
*/
#pragma once
class GZipAssistant
{public:GZipAssistant();~GZipAssistant();public:int Compress(const char *src, int srcLen, char *dest, int destLen);int Decompress(const char *src, int srcLen, const char *dst, int dstLen);static GZipAssistant* GetInstance(){static GZipAssistant ins;return &ins;}
};GZipAssistant* GetGZipAssistant();
/*
GZipAssisant.cpp
*/
#include "stdafx.h"
#include "../zlib/zlib.h"
#include "GZipAssisant.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endifGZipAssistant::GZipAssistant()
{}GZipAssistant::~GZipAssistant()
{}int GZipAssistant::Compress(const char *src, int srcLen, char *dest, int destLen)
{z_stream c_stream;int err = 0;int windowBits = 15;int GZIP_ENCODING = 16;if (src && srcLen > 0){c_stream.zalloc = (alloc_func)0;c_stream.zfree = (free_func)0;c_stream.opaque = (voidpf)0;if (deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,windowBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;c_stream.next_in = (Bytef *)src;c_stream.avail_in = srcLen;c_stream.next_out = (Bytef *)dest;c_stream.avail_out = destLen;while (c_stream.avail_in != 0 && c_stream.total_out < destLen){if (deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;}if (c_stream.avail_in != 0) return c_stream.avail_in;for (;;) {if ((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;if (err != Z_OK) return -1;}if (deflateEnd(&c_stream) != Z_OK) return -1;return c_stream.total_out;}return -1;
}int GZipAssistant::Decompress(const char *src, int srcLen, const char *dst, int dstLen) {z_stream strm;strm.zalloc = NULL;strm.zfree = NULL;strm.opaque = NULL;strm.avail_in = srcLen;strm.avail_out = dstLen;strm.next_in = (Bytef *)src;strm.next_out = (Bytef *)dst;int err = -1, ret = -1;err = inflateInit2(&strm, MAX_WBITS + 16);if (err == Z_OK) {err = inflate(&strm, Z_FINISH);if (err == Z_STREAM_END) {ret = strm.total_out;}else {inflateEnd(&strm);return err;}}else {inflateEnd(&strm);return err;}inflateEnd(&strm);return err;
}GZipAssistant* GetGZipAssistant()
{return GZipAssistant::GetInstance();
}
8.调用测试:
void CDemoDlg::OnBnClickedButtonGogogo()
{//压缩:const char* pSrc = "12312312313萨达萨达木alkjslngadaldn扩锁军,#¥@……@!#多绿蓑女所军副盘";int nLenSrc = strlen(pSrc);int nLenCompress = nLenSrc * 2;char* pCompressed = new char[nLenCompress];memset(pCompressed, 0, nLenCompress);int nLencompressed = GetGZipAssistant()->Compress(pSrc, nLenSrc, pCompressed, nLenCompress);if (nLencompressed <= 0){MessageBox("Compress Failed");}//解压缩:char* pDecompressed = new char[nLenSrc * 2];memset(pDecompressed, 0, nLenSrc * 2);int ret = GetGZipAssistant()->Decompress(pCompressed, nLencompressed, pDecompressed, nLenSrc * 2);CString str = pDecompressed;MessageBox(str);delete[] pCompressed;delete[] pDecompressed;
}
测试成功,Release版本的一样的套路,改改配置编译即可,亲测可行。
参考文章:
https://blog.csdn.net/moxiaomomo/article/details/52385837
https://www.cnblogs.com/lzhu/p/9602674.html
最新文章
- ubuntu linux下解决“no java virtual machine was found after searching the following locations:”的方法
- 用vector实现一个变长数组
- linux命令行ps1变量_Linux下SHELL的PS1变量简介
- Zabbix的架构配置选项
- MyCat实战--读写分离/数据分片/mycat集群/haproxy负载均衡
- 机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(五)
- linux设置超链接,帮助-链接 - Linux Kernel Newbies
- 比物理线程都好用的C++20的协程,你会用吗?
- Parcelable protocol requires a Parcelable.Creator object called。。。。。
- 在Node.js中,如何从其他文件中“包含”函数?
- 解决Android的adb命令行报错Permission denied
- android singletask启动模式,Android SingleTask启动模式与Home键的问题
- android投屏到web,网络视频投屏Web Video Cast v5.2.0 for Android 解锁高级版
- 整理出Android逆向系列学习进阶视频,全网疯传
- 中小型园区网典型配置
- 如何用计算机的if,if函数的使用方法(if函数的使用方法)
- android 驱动程序,安卓设备安装USB驱动程序教程
- 清除浮动解决高度坍塌的5种方法 以及兼容IE
- Redis入门(2):五大数据类型(key,string,list,set,sortset)将其实战,配置文件详解,发布与订阅
- 分享一个android手机开不了机的问题
热门文章
- Intel8086处理器使用NASM汇编语言实现操作系统04-实模式-屏幕显示不定长度的字符串(cmp/je)
- Fabrice Bellard其人 ---- FFMPEG及其他……
- =,==和===的区别
- panda3d 键盘移动场景
- 重读 构建Oracle高可用环境(一)
- 三大框架分别是Spring+SpringMVC+Mybatis ,这些东西必须融汇贯通
- 子查询中all与any的区别
- 机器学习——一元线性回归和多元线性回归
- 国产EDA工具Robei与Quartus ii联合使用(及在Rrobei设计中一些小技巧)
- 四个视频营销策略,让你火过傅园慧,Papi酱