Zlib文件压缩和解压

转载自:Known More

开源代码:http://www.zlib.net/

zlib使用手册: http://www.zlib.net/manual.html
zlib wince版: http://www.tenik.co.jp/~adachi/wince/
在这里,你可以查看基于各种操作系统平台的压缩与解缩代码实现。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
以下是经过测试的 WinCE 及 WinXP 下的代码

<<<<<<<<
第一步: 首先到http://www.zlib.net/下载个ZLIB,
             WinXP: 解压缩后打开zlib-1.2.3\projects\visualc6\zlib.dsw,选择Win32 LIB Release 按F7编绎生成zlib.lib, zlib.dll.
            WinCE: 下载一个for Windows CE 版的包,里面针对各种平台(ARM4, ARM4I, MIPS, X86)有对应的zlibce.dll zlibce.lib.

<<<<<<<<
第二步: 建立EVC 或者 VS2005 的对话框工程.
             在工程中添加以下文件:zlib.h, zconf.h, zlib.lib, zlib.dll (或者 zlibce.dll);
            这3个文件就在刚才从http://www.zlib.net/下载的软件包中.

<<<<<<<<
第三步: 包含头文件
#include "zlib.h"

主要使用fopen等C标准接口实现的,只用到zlib的Compress()和UnCompress()接口;里面的条件编译是针对PC和WCE的

封装的类:

class CZlib
{
public:
 CZlib();
 ~ CZlib();
 int Compress(char * DestName,const char *SrcName);
 int UnCompress(char * DestName,const char *SrcName);
};

接口实现:

压缩

复制代码
int  CZlib::Compress( char   *  DestName, const   char   * SrcName)
{
    
char  SourceBuffer[ 102400 =  { 0 };   // 压缩文件时的源buffer

    FILE
*  fp;   // 打开欲压缩文件时文件的指针
    FILE *  fp1;   // 创建压缩文件时的指针 

    errno_t err; 
// 错误变量的定义
#ifdef WINDOWS_PLATFORM
    err 
=  fopen_s( & fp,SrcName, " r+b " ); // 打开欲压缩的文件
     if (err)
    {
        printf(
" 文件打开失败! \n " );
        
return   1 ;
    }
#endif  
#ifdef    WINDOWS_CE_PLATFORM
    fp 
=  fopen_s(SrcName, " r+b " ); // 打开欲压缩的文件
if (fp)
    {
        printf(
" 文件打开失败! \n " );
        
return   1 ;
    }

#endif  

    
    
// 获取文件长度
     long  cur  =  ftell(fp);
    fseek(fp,
0L ,SEEK_END);
    
long  fileLength  =  ftell(fp);
    fseek(fp,cur,SEEK_SET);


    
// 读取文件到buffer
    fread(SourceBuffer,fileLength, 1 ,fp);
    fclose(fp);

    
// 压缩buffer中的数据
    uLongf SourceBufferLen = 102400 ;
    
char *  DestBuffer = ( char * )::calloc((uInt)SourceBufferLen,  1 );
    err
= compress((Bytef * )DestBuffer,(uLongf * ) & SourceBufferLen,( const  Bytef * )SourceBuffer,(uLongf)fileLength);
    
if (err != Z_OK)
    {
        cout
<< " 压缩失败: " << err << endl;
        
return   1 ;
    }
    
    
// 创建一个文件用来写入压缩后的数据
    err  =  fopen_s( & fp1, DestName, " w+b " );
    
if ( ! fp1)
    {
        printf(
" 压缩文件创建失败! \n " );
        
return   1  ;
    }

    fwrite(DestBuffer,SourceBufferLen,
1 ,fp1);
    fclose(fp1);
    
return   0 ;
}
复制代码

 

解压

复制代码
int  CZlib::UnCompress( char   *  DestName, const   char   * SrcName)
{
    
char  uSorceBuffer[ 102400 =  { 0 };   // 解压缩文件时的源buffer
    FILE *  fp3;   // 打开欲解压文件的文件指针
    FILE *  fp4;   // 创建解压文件的文件指针
    errno_t err;  // 错误变量的定义
    
// 打开欲解压的文件
    err  =  fopen_s( & fp3,SrcName, " r+b " );
    
if (err)
    {
        printf(
" 文件打开失败! \n " );
        
return   1 ;
    }

    
// 获取欲解压文件的大小
     long  ucur  =  ftell(fp3);
    fseek(fp3,
0L ,SEEK_END);
    
long  ufileLength  =  ftell(fp3);
    fseek(fp3,ucur,SEEK_SET);


    
// 读取文件到buffer
    fread(uSorceBuffer,ufileLength, 1 ,fp3);
    fclose(fp3);

    uLongf uDestBufferLen
= 1024000 ; // 此处长度需要足够大以容纳解压缩后数据
     char *  uDestBuffer = ( char * )::calloc((uInt)uDestBufferLen,  1 );
    
// 解压缩buffer中的数据
    err = uncompress((Bytef * )uDestBuffer,(uLongf * ) & uDestBufferLen,(Bytef * )uSorceBuffer,(uLongf)ufileLength);

    
if (err != Z_OK)
    {
        cout
<< " 解压缩失败: " << err << endl;
        
return   1 ;
    }

    
// 创建一个文件用来写入解压缩后的数据
    err  =  fopen_s( & fp4,DestName, " wb " );
    
if (err)
    {
        printf(
" 解压缩文件创建失败! \n " );
        
return   1  ;
    }

    printf(
" 写入数据... \n " );
    fwrite(uDestBuffer,uDestBufferLen,
1 ,fp4);
    fclose(fp4);
    
return   0 ;
}
复制代码

 


测试代码:

test.Compress("1.zip","test.docx");

test.UnCompress("11.docx","1.zip");

 

上述代码对于大文件就不适合了,因为是一次读出,一次写入的,下面是针对大文件的改进,分批读,分批写,代码如下:

 

复制代码
WF_Error CZlib::Compress( const   char   *  DestName, const   char   * SrcName)
{
    FILE 
*  fp_in  =  NULL; int  len  =   0 ; char  buf[ 16384 ];

    WF_Error re 
=  WF_OK;
    
    
if ( NULL  ==  (fp_in  =  fopen(SrcName, " rb " )))
    {
        
return  WF_FAIL;
    }

    
/
    gzFile  out   =  gzopen(DestName, " wb6f " );
    
    
if ( out   ==  NULL)
    {
        
return  WF_FAIL;
    }

    
for (;;)
    {
        len 
=  fread(buf, 1 , sizeof (buf),fp_in);
        
        
if (ferror(fp_in))
        {
            re 
=  WF_FAIL;
            
break ;
        }
        
        
if (len  ==   0 break ;

        
if (gzwrite( out , buf, (unsigned)len)  !=  len)
        {
            re 
=  WF_FAIL;
        }
    }

    gzclose(
out );

    fclose(fp_in);

    
return  re;
 }

 WF_Error CZlib::UnCompress(
const   char   *  DestName, const   char   * SrcName)
{
    FILE 
*  fp_out  =  NULL;WF_Error re  =  WF_OK;
    
    gzFile 
in ; int  len  =   0 ; char  buf[ 16384 ];

    
in   =  gzopen(SrcName, " rb " );

    
if ( in   ==  NULL)
    {
        
return  WF_FAIL;
    }

    
if (NULL  ==  (fp_out  =  fopen(DestName, " wb " )))
    {
        gzclose(
in );
        
return  WF_FAIL;
    }
    
    
for  (;;)
    {
        len 
=  gzread( in ,buf, sizeof (buf));

        
if (len  <   0 )
        {
            re 
=  WF_FAIL;
            
break ;
        }

        
if (len  ==   0 break ;

        
if (fwrite(buf, 1 ,(unsigned)len,fp_out) != len)
        {
            re 
=  WF_FAIL;
            
break ;
        }
    }

    fclose(fp_out);
    gzclose(
in );

    
return  re;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值