前几天和服务端同事联调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

最新文章

  1. ubuntu linux下解决“no java virtual machine was found after searching the following locations:”的方法
  2. 用vector实现一个变长数组
  3. linux命令行ps1变量_Linux下SHELL的PS1变量简介
  4. Zabbix的架构配置选项
  5. MyCat实战--读写分离/数据分片/mycat集群/haproxy负载均衡
  6. 机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(五)
  7. linux设置超链接,帮助-链接 - Linux Kernel Newbies
  8. 比物理线程都好用的C++20的协程,你会用吗?
  9. Parcelable protocol requires a Parcelable.Creator object called。。。。。
  10. 在Node.js中,如何从其他文件中“包含”函数?
  11. 解决Android的adb命令行报错Permission denied
  12. android singletask启动模式,Android SingleTask启动模式与Home键的问题
  13. android投屏到web,网络视频投屏Web Video Cast v5.2.0 for Android 解锁高级版
  14. 整理出Android逆向系列学习进阶视频,全网疯传
  15. 中小型园区网典型配置
  16. 如何用计算机的if,if函数的使用方法(if函数的使用方法)
  17. android 驱动程序,安卓设备安装USB驱动程序教程
  18. 清除浮动解决高度坍塌的5种方法 以及兼容IE
  19. Redis入门(2):五大数据类型(key,string,list,set,sortset)将其实战,配置文件详解,发布与订阅
  20. 分享一个android手机开不了机的问题

热门文章

  1. Intel8086处理器使用NASM汇编语言实现操作系统04-实模式-屏幕显示不定长度的字符串(cmp/je)
  2. Fabrice Bellard其人 ---- FFMPEG及其他……
  3. =,==和===的区别
  4. panda3d 键盘移动场景
  5. 重读 构建Oracle高可用环境(一)
  6. 三大框架分别是Spring+SpringMVC+Mybatis ,这些东西必须融汇贯通
  7. 子查询中all与any的区别
  8. 机器学习——一元线性回归和多元线性回归
  9. 国产EDA工具Robei与Quartus ii联合使用(及在Rrobei设计中一些小技巧)
  10. 四个视频营销策略,让你火过傅园慧,Papi酱