c++ zlib(qt)压缩与解压缩

出处:http://www.cnblogs.com/chuncn/archive/2011/03/23/1992481.html


zlib 是通用的压缩库,提供了一套 in-memory 压缩和解压函数,并能检测解压出来的数据的完整性(integrity)zlib 也支持读写 gzip (.gz) 格式的文件。下面介绍两个最有用的函数——compress  uncompress

 

int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);

compress函数将 source 缓冲区中的内容压缩到 dest 缓冲区。 sourceLen 表示source 缓冲区的大小(以字节计)。注意函数的第二个参数destLen 是传址调用。当调用函数时,destLen表示 dest 缓冲区的大小,destLen > (sourceLen + 12)*100.1%。当函数退出后,destLen 表示压缩后缓冲区的实际大小。此时 destLen / sourceLen 正好是压缩率。

compress 若成功,则返回 Z_OK;若没有足够内存,则返回 Z_MEM_ERROR;若输出缓冲区不够大,则返回 Z_BUF_ERROR

 

int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);

uncompress 函数将 source 缓冲区的内容解压缩到 dest 缓冲区。sourceLen  source 缓冲区的大小(以字节计)。注意函数的第二个参数destLen 是传址调用。当调用函数时,destLen 表示 dest 缓冲区的大小, dest 缓冲区要足以容下解压后的数据。在进行解压缩时,需要提前知道被压缩的数据解压出来会有多大。这就要求在进行压缩之前,保存原始数据的大小(也就是解压后的数据的大小)。这不是 zlib 函数库的功能,需要我们做额外的工作。当函数退出后, destLen 是解压出来的数据的实际大小。

uncompress 若成功,则返回 Z_OK ;若没有足够内存,则返回 Z_MEM_ERROR;若输出缓冲区不够大,则返回 Z_BUF_ERROR。若输入数据有误,则返回 Z_DATA_ERROR

zlib 带的 example.c 是个很好的学习范例,值得一观。我们写个程序,验证 zlib 的压缩功能。所写的测试程序保存为 testzlib.cpp ,放在zlib-1.1.4 目录下。程序源代码:

// testzlib.cpp  简单测试 zlib 的压缩功能

#include <cstring>

#include <cstdlib>

#include <iostream>

#include "zlib.h"

 

using namespace std;

 

int main()

{

    int err;

    Byte compr[200], uncompr[200];    // big enough

    uLong comprLen, uncomprLen;

    const char* hello = "12345678901234567890123456789012345678901234567890";

 

    uLong len = strlen(hello) + 1;

    comprLen  = sizeof(compr) / sizeof(compr[0]);

 

    err = compress(compr, &comprLen, (const Bytef*)hello, len);

 

    if (err != Z_OK) {

        cerr << "compess error: " << err << '\n';

        exit(1);

    }

    cout << "orignal size: " << len

         << " , compressed size : " << comprLen << '\n';

 

    strcpy((char*)uncompr, "garbage");

 

    err = uncompress(uncompr, &uncomprLen, compr, comprLen);

 

    if (err != Z_OK) {

        cerr << "uncompess error: " << err << '\n';

        exit(1);

    }

    cout << "orignal size: " << len

         << " , uncompressed size : " << uncomprLen << '\n';

 

    if (strcmp((char*)uncompr, hello)) {

        cerr << "BAD uncompress!!!\n";

        exit(1);

    } else {

        cout << "uncompress() succeed: \n" << (char *)uncompr;

    }

}

编译执行这个程序,输出应该是

D:\libpng\zlib-1.1.4>bcc32 testzlib.cpp zlib.lib

 

D:\libpng\zlib-1.1.4>testzlib

orignal size: 51 , compressed size : 22

orignal size: 51 , uncompressed size : 51

uncompress() succeed:

12345678901234567890123456789012345678901234567890

 

 
PS:这两个函数的一个很好的用处便是当需要将一个很占内存的变量写入文件以节省内存时,可以先压缩一下,然后写入文件,当需要使用时再从文件中读出,然后解压缩,以便节省IO时间。此外,有些情况可能还要序列化一下,当要压缩的内存不是一段连续的内存的时候。





c++ zlib(qt)压缩与解压缩

#include <QtCore/QCoreApplication>
#include "zlib.h"
#include "stdio.h"
#include <iostream>
using    namespace    std;
 
#define MaxBufferSize 999999
 
void  Test1();
void  Test2();
 
int  main( int  argc, char  *argv[])
{
     QCoreApplication a(argc, argv);
 
     //Test1();
     Test2();
     
     return  a.exec();
}
 
//c++ zlib
void  Test1()
{
     FILE* File_src;
     FILE* File_compress;
     FILE* File_uncompress;
 
     unsigned long  len_src;
     unsigned long  len_compress;
     unsigned long  len_uncompress;
 
     unsigned char  *buffer_src  = new  unsigned char [MaxBufferSize];
     unsigned char  *buffer_compress  = new  unsigned char [MaxBufferSize];
     unsigned char  *buffer_uncompress = new  unsigned char [MaxBufferSize];
 
     File_src = fopen( "src.txt" , "r" );
     File_compress = fopen( "compress.txt" , "w" );
     File_uncompress = fopen( "uncompress.txt" , "w" );
 
     //compress
     len_src = fread(buffer_src, sizeof ( char ),MaxBufferSize-1,File_src);
     compress(buffer_compress,&len_compress,buffer_src,len_src);
     fwrite(buffer_compress, sizeof ( char ),len_compress,File_compress);
     cout << "normal zlib:"  << endl;
     cout << "src:\n"  << buffer_src << ",length:"  << len_src << endl << endl;
     cout << "compress:\n"  << buffer_compress << ",length:"  << len_compress << endl << endl;
 
     //uncompress
     uncompress(buffer_uncompress,&len_uncompress,buffer_compress,len_compress);
     fwrite(buffer_uncompress, sizeof ( char ),len_uncompress,File_uncompress);
     cout << "uncompress:\n"  << buffer_uncompress << ",length:"  << len_uncompress << endl << endl;
 
     fclose(File_src);
     fclose(File_compress);
     fclose(File_uncompress);
}
 
//qt zlib
void  Test2()
{
     QByteArray src;
     src.append( "中华人民共和国,china mobile,123456" );
 
     unsigned long  len_compress;
     unsigned long  len_uncompress;
 
     unsigned char  *buffer_compress  = new  unsigned char [MaxBufferSize];
     unsigned char  *buffer_uncompress = new  unsigned char [MaxBufferSize];
 
     compress(buffer_compress,&len_compress,(Bytef*)src.data(), src.length());
     uncompress(buffer_uncompress,&len_uncompress,buffer_compress,len_compress);
 
     cout << "qt zlib:"  << endl;
     cout << "src:\n"  << src.data() << ",length:"  << src.size() << endl << endl;
     cout << "compress:\n"  << buffer_compress << ",length:"  << len_compress << endl << endl;
     cout << "uncompress:\n"  << buffer_uncompress << ",length:"  << len_uncompress << endl << endl;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值