压缩流程:
1.使用zlib做压缩,先调用deflateInit(),这个函数必须在使用deflate之前,zalloc,zfree和opaque等字段都是在deflateInit被初始化的,deflateInit将分配按照顺序分配内存空间,每次分配256K4.调用inflate()函数,这里不需要调整flush参数,但要注意inflate的返回值.
#include "zconf.h" #include "zlib.h" #include <string.h> // The one and only application object CWinApp theApp ; using namespace std ; #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include <fcntl.h> # include <io.h> # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) #endif #define CHUNK 16384 int def(FILE*source,FILE*dest,int level) { int ret,flush ; unsigned have ; z_stream strm ; unsigned char in[CHUNK]; unsigned char out[CHUNK]; /*allocate defalte state*/ strm.zalloc=Z_NULL ; strm.zfree=Z_NULL ; strm.opaque=Z_NULL ; ret=deflateInit(&strm,level); if(ret!=Z_OK) return ret ; do { strm.avail_in=fread(in,1,CHUNK,source); if(ferror(source)) { (void)deflateEnd(&strm); return Z_ERRNO ; } flush=feof(source)?Z_FINISH:Z_NO_FLUSH ; strm.next_in=in ; do { strm.avail_out=CHUNK ; strm.next_out=out ; ret=deflate(&strm,flush); have=CHUNK-strm.avail_out ; if(fwrite(out,1,have,dest)!=have||ferror(dest)) { (void)deflateEnd(&strm); return Z_ERRNO ; } //The way we tell that deflate() has no more output is by seeing that it did not fill the output buffer, //leaving avail_out greater than zero. } while(strm.avail_out==0); } while(flush!=Z_FINISH); (void)deflateEnd(&strm); return Z_OK ; } int inf(FILE*source,FILE*dest) { int ret ; unsigned have ; z_stream strm ; unsigned char in[CHUNK]; unsigned char out[CHUNK]; strm.zalloc=Z_NULL ; strm.zfree=Z_NULL ; strm.opaque=Z_NULL ; strm.avail_in=0 ; strm.next_in=Z_NULL ; ret=inflateInit(&strm); if(ret!=Z_OK) return ret ; do { strm.avail_in=fread(in,1,CHUNK,source); if(ferror(source)) { (void)inflateEnd(&strm); return Z_ERRNO ; } if(0==strm.avail_in) break ; strm.next_in=in ; do { strm.avail_out=CHUNK ; strm.next_out=out ; ret=inflate(&strm,Z_NO_FLUSH); switch(ret) { case Z_NEED_DICT : ret=Z_DATA_ERROR ; case Z_DATA_ERROR : case Z_MEM_ERROR : (void)inflateEnd(&strm); return ret ; } have=CHUNK-strm.avail_out ; if(fwrite(out,1,have,dest)!=have||ferror(dest)) { (void)inflateEnd(&strm); return Z_ERRNO ; } } while(strm.avail_out==0); } while(ret!=Z_STREAM_END); (void)inflateEnd(&strm); return ret=Z_STREAM_END?Z_OK:Z_DATA_ERROR ; } void zerr(int ret) { fputs("zpipe: ",stderr); switch(ret) { case Z_ERRNO : if(ferror(stdin)) fputs("error reading stdin/n",stderr); if(ferror(stdout)) fputs("error writing stdout/n",stderr); break ; case Z_STREAM_ERROR : fputs("invalid compression level/n",stderr); break ; case Z_DATA_ERROR : fputs("invalid or incomplete deflate data/n",stderr); break ; case Z_MEM_ERROR : fputs("out of memory/n",stderr); break ; case Z_VERSION_ERROR : fputs("zlib version mismatch!/n",stderr); } } int _tmain(int argc,TCHAR*argv[],TCHAR*envp[]) { int nRetCode=0 ; // initialize MFC and print and error on failure if(!AfxWinInit(:: GetModuleHandle(NULL),NULL,:: GetCommandLine(),0)) { // TODO: change error code to suit your needs _tprintf(_T("Fatal Error: MFC initialization failed/n")); nRetCode=1 ; } else { // TODO: code your application's behavior here. } int ret ; SET_BINARY_MODE(stdin); SET_BINARY_MODE(stdout); if(argc==1) { ret=def(stdin,stdout,Z_DEFAULT_COMPRESSION); if(ret!=Z_OK) zerr(ret); return ret ; } else if(argc==2&&strcmp(argv[1],"-d")==0) { ret=inf(stdin,stdout); if(ret!=Z_OK) zerr(ret); return ret ; } else { fputs("zpipe usage: zpipe [-d] < source > dest/n",stderr); } return nRetCode ; }Zlib的deflate, z_stream结构的使用
以上完成了一次压缩
更多细节:http://www.zlib.net/zlib_how.html