[充電][庫]Zlib文件壓縮和解壓


原文鏈接: http://www.cnblogs.com/fairycao/archive/2009/12/09/1620414.html

開源代碼: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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM