博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用开源库zlib压缩和解压文件
阅读量:2193 次
发布时间:2019-05-02

本文共 3095 字,大约阅读时间需要 10 分钟。

http://blog.csdn.net/zhu2695/article/details/51285985

zlib,一个十分强大的开源压缩解压库,应用示范广泛,很多开源库中都有它的存在(libpng,libzplay,ffmpeg……)。

作为普通开发者只要掌握其主要的两个函数就足够用了:

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

compress函数将 source 缓冲区中的内容压缩到 dest 缓冲区。 sourceLen 表示

source 缓冲区的大小(以字节计)。注意函数的第二个参数 destLen 是传址调用。当调用函数时,destLen表示 dest 缓冲区的大小,destLen > (sourceLen + 12)*100.1%。

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

uncompress 函数将 source 缓冲区的内容解压缩到 dest 缓冲区。sourceLen 是

source 缓冲区的大小(以字节计)。注意函数的第二个参数 destLen 是传址调用。当调用函数时,destLen 表示 dest 缓冲区的大小, dest 缓冲区要足以容下解压后的数据。

在进行解压缩时,需要提前知道被压缩的数据解压出来会有多大。这就要求在进行压缩之前,保存原始数据的大小(也就是解压后的数据的大小)。这不是 zlib 函数库的功能,需

要我们做额外的工作。当函数退出后, destLen 是解压出来的数据的实际大小。

看一个小例子:

[cpp]   
  1. / zlibDemo.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "zlib.h"  
  6. #include <assert.h>  
  7. #include <Windows.h>  
  8. #include <iostream>  
  9. using std::cout;  
  10. using std::endl;  
  11. //静态加载如下:  
  12. //#pragma comment(lib,"zlib1")  
  13. const char* pFileCom="..\\Debug\\save.xml";//源文件  
  14. const char* pFileSave="..\\Debug\\1.zip";//压缩后的文件  
  15. #define MAX_LEN 1024*100//本例只适用于小于100KB的文件  
  16. int _tmain(int argc, _TCHAR* argv[])  
  17. {  
  18.     //压缩文件  
  19.     FILE* fp1=NULL;  
  20.     fp1=fopen(pFileCom,"rb");  
  21.     assert(fp1);  
  22.     //申请缓冲区  
  23.     unsigned char* pBufferRes=new unsigned char[MAX_LEN];  
  24.     unsigned char* pBufferDes=new unsigned char[MAX_LEN];  
  25.     //置零  
  26.     memset(pBufferRes,0,MAX_LEN);  
  27.     memset(pBufferDes,0,MAX_LEN);  
  28.     //读取整个文件到缓冲区  
  29.     fread(pBufferRes,sizeof(unsigned char),MAX_LEN-1,fp1);  
  30.     uLongf lSize=strlen((const char*)pBufferRes);  
  31.     //动态加载DLL  
  32.     HINSTANCE hIns=::LoadLibrary(_T("..\\Debug\\zlib1.dll"));  
  33.     uLongf desLen;  
  34.     if(hIns)  
  35.     {  
  36.         typedef int (*fun)(Bytef*,uLongf*,const Bytef*,uLongf);  
  37.         fun f=NULL;  
  38.         //指向函数地址的指针  
  39.         f=(fun)GetProcAddress(hIns,"compress");  
  40.         if(f==NULL)  
  41.         {  
  42.             cout<<"获取模块函数地址失败!"<<endl;  
  43.             ::FreeLibrary(hIns);  
  44.             return 1;  
  45.         }  
  46.         int nError=f(pBufferDes,&desLen,pBufferRes,lSize);  
  47.         //desLen必须大于lsize,详情请参照zlib文档  
  48.         if(nError!=Z_OK)  
  49.         {  
  50.             cout<<"压缩失败!"<<endl;  
  51.             ::FreeLibrary(hIns);  
  52.             fclose(fp1);  
  53.             return 1;  
  54.         }  
  55.         cout<<"压缩成功,压缩率为: %"<<desLen/(float)lSize*100<<endl;  
  56.     }  
  57.     else  
  58.     {  
  59.         cout<<"加载库文件失败!"<<endl;  
  60.         return 1;  
  61.     }  
  62.     fclose(fp1);  
  63.     FILE* fp2=NULL;  
  64.     fp2=fopen(pFileSave,"wb");  
  65.     //将压缩后的信息写入文件  
  66.     fwrite(pBufferDes,sizeof(unsigned char),desLen,fp2);  
  67.     fclose(fp2);  
  68.     /  
  69.     //解压文件  
  70.     memset(pBufferDes,0,MAX_LEN);  
  71.     memset(pBufferRes,0,MAX_LEN);  
  72.     fp1=fopen("..\\Debug\\1.zip","rb");  
  73.     desLen=fread(pBufferRes,1,desLen,fp1);  
  74.     typedef int (*unFun)(Bytef*,uLongf*,const Bytef*,uLongf);  
  75.     unFun uf=NULL;  
  76.     uf=(unFun)GetProcAddress(hIns,"uncompress");  
  77.     uLongf unSize;  
  78.     if(uf)  
  79.     {  
  80.         int nRet=uf(pBufferDes,&unSize,pBufferRes,desLen);  
  81.         ::FreeLibrary(hIns);  
  82.         if(nRet!=Z_OK)  
  83.         {  
  84.             cout<<"解压缩失败"<<endl;  
  85.             fclose(fp1);  
  86.             return 1;  
  87.         }  
  88.     }  
  89.     fclose(fp1);  
  90.     fp2=fopen("..\\Debug\\uncompress.xml","wb");  
  91.     fwrite(pBufferDes,1,unSize,fp2);  
  92.     fclose(fp2);  
  93.     cout<<"成功解压文件"<<pFileSave<<"到uncompress.xml"<<endl;  
[cpp]   
  1.     //释放申请的内存空间  
  2.     delete[] pBufferDes;  
  3.     pBufferDes=NULL;  
  4.     delete[] pBufferRes;  
  5.     pBufferRes=NULL;  
  6.     return 0;  
  7. }  
  8.   
  9. /*zlib中两个主要函数的声明: 
  10. int compress OF((Bytef *dest,   uLongf *destLen,const Bytef *source, uLong sourceLen)); 
  11. int uncompress OF((Bytef *dest,   uLongf *destLen,const Bytef *source, uLong sourceLen));*/  

运行程序,结果如下:

下载地址:

              

你可能感兴趣的文章
Leetcode C++《热题 Hot 100-29》22.括号生成
查看>>
Leetcode C++《热题 Hot 100-47》236.二叉树的最近公共祖先
查看>>
Leetcode C++《热题 Hot 100-48》406.根据身高重建队列
查看>>
《kubernetes权威指南·第四版》第二章:kubernetes安装配置指南
查看>>
Leetcode C++《热题 Hot 100-49》399.除法求值
查看>>
Leetcode C++《热题 Hot 100-51》152. 乘积最大子序列
查看>>
Leetcode C++ 《第181场周赛-1》 5364. 按既定顺序创建目标数组
查看>>
Leetcode C++ 《第181场周赛-2》 1390. 四因数
查看>>
阿里云《云原生》公开课笔记 第一章 云原生启蒙
查看>>
阿里云《云原生》公开课笔记 第二章 容器基本概念
查看>>
阿里云《云原生》公开课笔记 第三章 kubernetes核心概念
查看>>
阿里云《云原生》公开课笔记 第四章 理解Pod和容器设计模式
查看>>
阿里云《云原生》公开课笔记 第五章 应用编排与管理
查看>>
阿里云《云原生》公开课笔记 第六章 应用编排与管理:Deployment
查看>>
阿里云《云原生》公开课笔记 第七章 应用编排与管理:Job和DaemonSet
查看>>
阿里云《云原生》公开课笔记 第八章 应用配置管理
查看>>
阿里云《云原生》公开课笔记 第九章 应用存储和持久化数据卷:核心知识
查看>>
linux系统 阿里云源
查看>>
国内外helm源记录
查看>>
牛客网题目1:最大数
查看>>