QT-GZIP压缩解压

项目中http上报数据需要先用gzip进行压缩,参考了很多资料之后,利用QT本身自带的zlib封装了压缩和解压的两个方法:

#include 
#include 
QByteArray Compress(QByteArray postBody)
{
	QByteArray outBuf;
	z_stream c_stream;
	int err = 0;
	int windowBits = 15;
	int GZIP_ENCODING = 16;
	if (!postBody.isEmpty())
	{
		c_stream.zalloc = (alloc_func)0;
		c_stream.zfree = (free_func)0;
		c_stream.opaque = (voidpf)0;
		c_stream.next_in = (Bytef *)postBody.data();
		c_stream.avail_in = postBody.size();
		if (deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
			MAX_WBITS + GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY) != Z_OK) return QByteArray();
		for (;;) {
			char destBuf[4096] = { 0 };
			c_stream.next_out = (Bytef *)destBuf;
			c_stream.avail_out = 4096;
			int err = deflate(&c_stream, Z_FINISH);
			outBuf.append(destBuf, 4096 - c_stream.avail_out);
			if (err == Z_STREAM_END || err != Z_OK)
			{
				break;
			}
		}
		auto total = c_stream.total_out;
		deflateEnd(&c_stream);
		total = c_stream.total_out;
	}
	return outBuf;
}


QByteArray UnCompress(QByteArray src)
{
	QByteArray outBuffer;
	z_stream strm;
	strm.zalloc = NULL;
	strm.zfree = NULL;
	strm.opaque = NULL;

	strm.avail_in = src.size();
	strm.next_in = (Bytef *)src.data();

	int err = -1, ret = -1;
	err = inflateInit2(&strm, MAX_WBITS + 16);
	if (err == Z_OK) {
		while (true)
		{
			char buffer[4096] = { 0 };
			strm.avail_out = 4096;
			strm.next_out = (Bytef *)buffer;
			int code = inflate(&strm, Z_FINISH);
			outBuffer.append(buffer, 4096 - strm.avail_out);
			if (Z_STREAM_END == code || Z_OK != code)
			{
				break;
			}
		}
	}
	inflateEnd(&strm);
	return outBuffer;
}

这里有一个点需要注意,就是outBuffer.append(buffer, 4096 - strm.avail_out);在append的时候加入了长度的参数也是为了明确指出增加数据量。如果不指出这个量,字符串中包含0就会认为字符串结束了,不会再copy后面的数据了。

 

gzip的压缩和加压需要deflateInit2和inflateInit2初始化参数,gzip需要设置windowbits参数为MAX_WBITS + 16,下面是网上找到的解释:Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper.

你可能感兴趣的:(QT)