Zlib文件压缩和解压

来源:互联网 发布:orcad怎么导出网络表 编辑:程序博客网 时间:2024/05/01 12:35

Zlib文件压缩和解压

开源代码: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);

};

接口实现:

压缩

Zlib文件压缩和解压 - GingKo - 花猫揍Zlib文件压缩和解压 - GingKo - 花猫揍代码

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;

}

 

解压

Zlib文件压缩和解压 - GingKo - 花猫揍Zlib文件压缩和解压 - GingKo - 花猫揍代码

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");

 

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

 

Zlib文件压缩和解压 - GingKo - 花猫揍Zlib文件压缩和解压 - GingKo - 花猫揍代码

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;

}

原创粉丝点击