场景
1.一般在使用文本json传输数据, 数据量特别大时,传输的过程就特别耗时, 因为带宽或者socket的缓存是有限制的, 数据量越大, 传输时间就越长. 网站一般使用gzip来压缩成二进制.
说明
1.zlib库可以实现gzip和zip方式的压缩, 这里只介绍zip方式的二进制压缩, 压缩比还是比较可观的, 一般写客户端程序已足够.
2.修改了一下zpipe.c的实现, 其实就是把读文件改为读字符串, 写文件改为写字符串即可.
例子
#include "stdafx.h"
#include <string>
#include <iostream>
#include <memory>
#include <assert.h>
#include "zlib.h"
#define CHUNK 16384
int CompressString(
const char* in_str,size_t in_len,
std::
string& out_str,
int level)
{
if(!in_str)
return Z_DATA_ERROR;
int ret, flush;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
std::
shared_ptr<z_stream> sp_strm(&strm,[](z_stream* strm){
(
void)deflateEnd(strm);
});
const char* end = in_str+in_len;
size_t pos_index =
0;
size_t distance =
0;
do {
distance = end - in_str;
strm.avail_in = (distance>=CHUNK)?CHUNK:distance;
strm.next_in = (Bytef*)in_str;
in_str+= strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush);
if(ret == Z_STREAM_ERROR)
break;
have = CHUNK - strm.avail_out;
out_str.append((
const char*)out,have);
}
while (strm.avail_out ==
0);
if(strm.avail_in !=
0);
break;
}
while (flush != Z_FINISH);
if(ret != Z_STREAM_END)
return Z_STREAM_ERROR;
return Z_OK;
}
int DecompressString(
const char* in_str,size_t in_len,
std::
string& out_str)
{
if(!in_str)
return Z_DATA_ERROR;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in =
0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
std::
shared_ptr<z_stream> sp_strm(&strm,[](z_stream* strm){
(
void)inflateEnd(strm);
});
const char* end = in_str+in_len;
size_t pos_index =
0;
size_t distance =
0;
int flush =
0;
do {
distance = end - in_str;
strm.avail_in = (distance>=CHUNK)?CHUNK:distance;
strm.next_in = (Bytef*)in_str;
in_str+= strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if(ret == Z_STREAM_ERROR)
break;
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
have = CHUNK - strm.avail_out;
out_str.append((
const char*)out,have);
}
while (strm.avail_out ==
0);
}
while (flush != Z_FINISH);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
int _tmain(
int argc, _TCHAR* argv[])
{
const char* buf =
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"01010101010101010101010000000000000000000000000000011111111111111"
"qwertyuiop[]";
std::
cout <<
"========= CompressString ===========" <<
std::endl;
std::
cout <<
"Source Buffer Size: " <<
strlen(buf) <<
std::endl;
std::
string out_compress;
assert(CompressString(buf,
strlen(buf),out_compress,Z_DEFAULT_COMPRESSION) == Z_OK);
std::
cout <<
"Compress Buffer Size: " << out_compress.size() <<
std::endl;
std::
cout <<
"========= DecompressString ===========" <<
std::endl;
std::
string out_decompress;
assert(DecompressString(out_compress.c_str(),out_compress.size(),out_decompress) == Z_OK);
std::
cout <<
"Decompress Buffer Size: " << out_decompress.size() <<
std::endl;
assert(!out_decompress.compare(buf));
return 0;
}
输出:
=
======== CompressString ===========
Source Buffer Size: 662
Compress Buffer Size: 38
=
======== DecompressString ===========
Decompress Buffer Size: 662
参考
zlib\src\examples\zpipe.c
C++ Code Snippet - Compressing STL Strings with zlib
转载请注明原文地址: https://ju.6miu.com/read-271297.html