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);
};
接口实现:
压缩
{
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 ;
}
解压
{
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");
上述代码对于大文件就不适合了,因为是一次读出,一次写入的,下面是针对大文件的改进,分批读,分批写,代码如下:
{
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;
}