C++zlib库实现的GZIP压缩解压缩工具类【多图警告^

C++zlib库实现的GZIP压缩解压缩工具类【多图警告^,第1张

C++zlib库实现的GZIP压缩解压缩工具类【多图警告^

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5690563.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存