博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Zlib文件压缩和解压
阅读量:5104 次
发布时间:2019-06-13

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

 

开源代码:
zlib使用手册:
zlib wince版:
在这里,你可以查看基于各种操作系统平台的压缩与解缩代码实现。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

<<<<<<<<

第一步: 首先到下载个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个文件就在刚才从下载的软件包中.

<<<<<<<<

第三步: 包含头文件
#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;
}

转载于:https://www.cnblogs.com/lvdongjie/p/4788602.html

你可能感兴趣的文章
poj 1562 Oil Deposits(dfs)
查看>>
bzoj2751--[HAOI]2012容易题--组合(乘法原理)
查看>>
演示使用sql_trace和10046事件对其他会话进行跟踪,并给出trace结果
查看>>
【转】错误:分析 EntityName 时出错
查看>>
字符串
查看>>
Delete an Array / Expanding a Current Array via DS Storage Manager
查看>>
hdu 2586 lca在线算法(朴素算法)
查看>>
[转] 查看HDFS文件系统数据的三种方法
查看>>
JDBC工具类完整版!
查看>>
dom初识
查看>>
java+搜索引擎
查看>>
【Nginx】发送响应
查看>>
读性能测试进阶指南-笔记(一)
查看>>
亚信第五天
查看>>
mongodb工具类
查看>>
在windows上安装docker
查看>>
列表操作
查看>>
让nginx支持PATH_INFO
查看>>
Lazy方法
查看>>
PS切图采坑
查看>>