前几天和服务端同事联调TCP传输压缩后的Json串,遇到了 GZIP压缩问题。
需要把原来使用的的压缩算法和后端统一,现在来总结一下。
【注意】 这里就以Windows的Debug环境为例,Release版也是一样,只需更改配置编译就好。
代码演示中不未涉及文件序列化问题。文件(文件夹)压缩问题,可以参考zip压缩文章Zip压缩解压缩
1.下载zlib源码及工程文件:
https://www.zlib.net/
2.拿到源码包解压看看
3.打开目录zlib-1.2.11contribvstudiovc12下的解决方案:
一堆错误,编译失败:
解决方案:https://www.cnblogs.com/lzhu/p/9602674.html
我在示例中使用的VS2013编译的VC12的示例解决方案,报错。得把这六个工程都修复下:
编译成功:
4.编译成功,得到库文件:
打开工程目录,从x86ZlibDllDebug下拿到库文件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到工程里面:
#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();
#include "stdafx.h" #include "../zlib/zlib.h" #include "GZipAssisant.h" #ifdef _DEBUG #define new DEBUG_NEW #endif GZipAssistant::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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)