zlib库使用简单讲解

您所在的位置:网站首页 stream软件干什么用 zlib库使用简单讲解

zlib库使用简单讲解

2024-03-28 08:45| 来源: 网络整理| 查看: 265

本文转载自:http://blog.csdn.net/ostar_liang/article/details/16898089

1.zlib库简介

   zlib 是通用的压缩库,提供了一套 in-memory 压缩和解压函数,并能检测解压出来的数据的完整性(integrity)。zlib 也支持读写 gzip (.gz) 格式的文件。源码网址:http://www.gzip.org/zlib/。

   默认且目前仅使用deflate算法压缩data部分;deflate是一种压缩算法,是huffman编码的一种加强。

  

2、zlib中函数解析

(1)压缩: int compress(unsigned char * dest, unsigned long * destLen, unsigned char * source, unsigned long sourceLen); dest:压缩后数据保存的目标缓冲区 destLen:目标缓冲区的大小(必须在调用前设置,并且它是一个指针) source:要压缩的数据 sourceLen:要压缩的数据长度 compress()函数成功返回Z_OK,如果内存不够,返回Z_MEM_ERROR,如果目标缓冲区太小,返回Z_BUF_ERROR int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); level: 相比上面一个增加了压缩级别 (2)解压缩: int uncompress(unsigned char * dest,  unsigned long * destLen, unsigned char * source, unsigned long sourceLen); dest:解压后数据保存的目标缓冲区 destLen:目标缓冲区的大小(必须在调用前设置,并且它是一个指针) source:要解压的数据 sourceLen:要解压的数据长度 uncompress()函数成功返回Z_OK,如果内存不够,返回Z_MEM_ERROR,如果目标缓冲区太小,返回Z_BUF_ERROR,如果要解压的数据损坏或不完整,返回Z_DATA_ERROR。

     压缩和解压缩的例子可以参照Lib库中的函数test_compress。

 

zlib使用过程 压缩过程:deflateInit() ->deflate() ->deflateEnd();  对应的解压过程 inflateInit() ->   inflate() ->   inflateEnd();  压缩过程:deflateInit2() ->deflate() ->deflateEnd();  对应的解压过程 inflateInit2() ->  inflate() ->  inflateEnd(); 常用的数据结构 typedef struct z_stream_s {     z_const Bytef  *next_in;                     // 将要压缩数据的首地址     uInt                 avail_in;                      // 将要压缩数据的长度     uLong             total_in;                       // 将要压缩数据缓冲区的长度     Bytef               *next_out;                    // 压缩后数据保存位置。     uInt                 avail_out;                     // 压缩后数据的长度     uLong             total_out;                     // 压缩后数据缓冲区的大小     z_const char   *msg;                           // 存放最近的错误信息,NULL表示没有错误     struct internal_state FAR *state; /* not visible by applications */     alloc_func        zalloc;  /* used to allocate the internal state */     free_func         zfree;   /* used to free the internal state */     voidpf              opaque;  /* private data object passed to zalloc and zfree */     int                   data_type;                     // 表示数据类型,文本或者二进制     uLong             adler;      /* adler32 value of the uncompressed data */     uLong             reserved;   /* reserved for future use */ }  z_stream;

对于z_stream我们一般使用     z_stream stream; 常用的函数 include: zlib.h int deflateInit ((z_streamp strm, int level));     description: 初始化压缩状态,关联相关的z_stream数据结构和压缩比例     parameter:         strm:   要关联的z_stream数据结构         level: 压缩比例,压缩级别是一个0-9的数字,0压缩速度最快(压缩的过程),9压缩速度最慢,压缩率最大,0不压缩数据 int deflateInit2 ((z_streamp strm, int  level, int  method, int  windowBits, int  memLevel, int  strategy));     description: 压缩的初始化     parameter:         strm:   关联的数据结构            level:  压缩级别,压缩级别是一个0-9的数字,0压缩速度最快(压缩的过程),9压缩速度最慢,压缩率最大,0不压缩数         method: 压缩的模式,现在只有一种。Z_DEFLATED(表示数字8)         windowBits: 表示处理raw deflate的方法。windowBits为8..15,也可以为-8...-15。当值为16时,将会加上一个简单gzip头部和尾部。         memLevel:   指定的内部压缩状态,应该分配多少内存。 memLevel=1使用的最小内存,但很慢,降低了压缩比; memLevel=9使用的最大内存以获得最佳的速度。默认值是8。请参阅作为的函数windowBits和memLevel的使用的总内存zconf.h。         strategy:   压缩的策略 int deflate ((z_streamp strm, int flush));     description: 压缩数据     parameter:         strm:   关联的数据结构,要压缩的数据、长度、压缩数据的存放位置和可用大小,都在其中设置的         flush:  采用何种法师将压缩的数据写到缓冲区中。 int deflateEnd ((z_streamp strm))     description: 压缩结束     parameter:         strm:   关联的数据结构,释放资源 基本函数: int deflateInit (z_streamp strm, int level); int deflate (z_streamp strm, int flush); int deflateEnd (z_streamp strm); int inflateInit (z_streamp strm); int inflate (z_streamp strm, int flush); int inflateEnd (z_streamp strm);

关键函数是deflate进行压缩,inflate进行解压。

deflate函数有两个参数,stream和flush。stream是一个结构体变量,有next_in、avail_in、next_out、avail_out这四个变量。next_in表示当前输入的字节数组,avail_in表示当前可用的输入字节数;next_out表示当前输出的字节数组,avail_out表示当前可用的输出字节数。当输入数据没有结束时flush设为Z_NO_FLUSH,否则设为Z_FINISH。next_out要至少比next_in大0.0015%。

inflate函数参数和deflate相同,但flush总是设为Z_NO_FLUSH。

 

deflate和inflate的例子参照example.c中的test_deflate和test_inflate函数

 

gzip(*.gz)档案格式几乎是Linux下的标准格式了,有人认为bzip2的压缩率比gzip来得高。一般来说,这个说法大致正确,不过根据我个人的经验,有一半以上的档案,bzip2没有比gzip的压缩率来得高,有少数状况下,gzip压缩率反而比bzip2来的高。    zlib是个支援gzip档案格式的函数库,它使得gz档的存取就犹如开档关档一样  地容易,您可以很容易地为您的程序加入gz档的支援。 

函数宣告      gzFile gzopen  (const char *path, const char *mode);      开启一个gzip(*.gz)档。       mode叁数可为"rb"或"wb"。       另外也可包含压缩程度如"wb9"。       用'f'作为过滤资料,如"wb6f"。       用'h'可指定Huffman only压缩,如"wb1h"       gzopen亦可用於读取非压缩的gzip档案格式,在这种状况下,gzread会直接读      取,而不进行解压缩。    int gzread (gzFile file, voidp buf, unsigned len);      与read的用法相同。    int gzwrite (gzFile file, const voidp buf, unsigned len);      与write用法相同。    int gzprintf (gzFile file, const char *format, ...);      与fprintf用法相同。    char * gzgets (gzFile file, char *buf, int len);      与fgets用法相同。    int gzputc (gzFile file, int c);      与fputc用法相同。    int gzgetc (gzFile file);      与fgetc用法相同。    int gzflush (gzFile file, int flush);      与fflush作用相同。    z_off_t gzseek (gzFile file, z_off_t offset, int whence);      whence不支援SEEK_END      如果档案是开启为"读取",则SEEK_SET及SEEK_CUR,向前及向後均支援,不过     很慢就是了。      如果档案是开启为"写入",仅支援向前SEEK。    int gzrewind (gzFile file);      与gzseek(file, 0L, SEEK_SET)相同作用,仅在读取时有效。    z_off_t gztell (gzFile file);      返回值 : 目前档案位置(解压缩後的位置)    int gzeof (gzFile file);      返回值 : 1 - EOF, 0 - not EOF    int gzclose (gzFile file);      关闭档案      返回值 : zlib error number      ==================================================================== zlib是一个通用的压缩开源库,提供了在内存中压缩和解压的函数,包括对解压后数据的校验。目前版本的zlib只支持deflate方法,但是其它的方法将会被添加进来并且拥有同样的接口。

—— zlib manaul     deflate算法在rfc1951中有详细的说明。     zlib同时又是一种数据格式,使用zlib库压缩后的数据会在deflate数据的头和尾添加信息,形成zlib格式的数据。

   gzip也是一种数据压缩格式,可以大体分为头部,数据部和尾部三个部分,其中头部和尾部主要是一些文档属性和校验信息(rfc1952),数据部主要是用deflate方法压缩得到的数据。         zlib库默认的压缩方法并不是gzip的,而是zlib的,因此使用zlib压缩得到gzip格式的数据有两种方法:

使用zlib提供的gz***系列函数可以直接把想要的内容写入一个磁盘gzip文件; 如果想在内存中生成gzip格式的数据,可以在初始化的时候调用inflateInit2函数,并指定为gzip格式,代码如下:

   

  z_stream d_stream;   d_stream.zalloc = NULL;   d_stream.zfree = NULL;   d_stream.opaque = NULL;   int ret = deflateInit2(&d_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, DEFAULT_WINDOWSIZE, DEFAULT_MEMLEVEL,  Z_DEFAULT_STRATEGY);   if (Z_OK != ret)   {     printf("init deflate error\n");     return ret;   }

    之后,用deflate压缩出来的数据就是gzip的了

 

    gzip的参照example.c中的test_gzio函数,最终会生成一个foo.gz的压缩包。并能够通过gzread读出压缩中的数据。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3