返回> 网站首页
zlib.h使用概述
yoours2016-05-13 13:15:13
简介一边听听音乐,一边写写文章。
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
这里的OF其实就是zconf里的一个定义:
#ifndef OF
#
#
#
#
#
#endif
大概意思就是用在参数列表前面,有什么作用?不了解,不明白。
ZEXTERN就是extern,ZEXPORT的作用不明白,不了解
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
为压缩初始化流状态,level必须设置为Z_DEFAULT_COMPRESSION(-1)或者0~9。
返回值:Z_OK 成功
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
压缩尽可能多的输入数据,input缓存空了或者output缓存满了时停止。
就是说,每次读入的输入数据尽可能多,但每次的输出数据都正好将输出缓冲区填满(最后一次除外,可能填不满)
如果没有强制flush,该函数会有输出“延迟”,即读入输入,但却没有产生任何输出
返回值:Z_OK 压缩了更多的输入数据(相比之前)或者产生了更多的输出(相比之前)
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
结束压缩过程,为该stream动态分配的所有内存被释放,未处理的输入被丢弃,未输出的输出(输出延迟所致)也被丢弃
返回值:
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
为解压初始化流状态
返回值:Z_OK 成功
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
解压尽量多的输入数据,input缓存空了或者output缓存满了时停止。
就是说,每次读入的输入数据尽可能多,但每次的输出数据都正好将输出缓冲区填满(最后一次除外,可能填不满)
如果没有强制flush,该函数会有输出“延迟”,即读入输入,但却没有产生任何输出
返回值:Z_OK 解压了更多的输入数据(相比之前)或者产生了更多的输出(相比之前)
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
结束解压过程,为该stream动态分配的所有内存被释放,未处理的输入被丢弃,未输出的输出(输出延迟所致)也被丢弃
返回值:Z_OK 成功
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
目前版本method参数必须设为Z_DEFLATED
windowBits参数是窗口大小以2为底求的对数(历史缓冲区的大小)。目前版本应在8~15之间,值越大,将耗费更多的内存,同时带来更好的压缩结果。如果使用deflateInit,默认的windowBits是15.
windowBits也可以置为-15~-8,表示要进行的是原始压缩,-windowBits值决定了窗口大小。接下来deflate将产生无zlib头部和尾部的原始压缩数据,也不会计算adler32校验值。
如果要进行gzip压缩,windowBits也可以比15大。windowBits置为16将在压缩后的数据前后加上gzip头部和尾部,而不是zlib的头尾部。
memLevel为1~9,数值越大,the internal compression state(什么意思?不知道)占用的内存也越大,但是速度也越快。默认为8
strategy用于调整压缩算法,一般置为Z_DEFAULT_STRATEGY
返回值:
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
windowBits参数是窗口大小以2为底求的对数(历史缓冲区的大小)。目前版本应在8~15之间,值越大,将耗费更多的内存,同时带来更好的压缩结果。如果使用inflateInit,默认的windowBits是15.
windowBits也可以置为0,以使用经zlib压缩的流(即strm)头部中的window size
windowBits也可以置为-15~-8,表示要进行的是原始解压,-windowBits值决定了窗口大小。不寻找zlib或gzip头部,不产生校验值,不在输入流尾寻找任何校验值。该方法用于解压其它利用了deflate压缩方法的格式,如zip。这些格式有自己的校验值。
windowBits也可以比15大,以进行gzip解压。在windowBits(指的是原来的8~15或者-15~-8)上加上32来自动识别zlib和gzip(所以要解压http中的gzip部分,一般是置为15+32=47)。或者在windowBits上加上16,仅解码gzip格式,此时zlib格式会返回Z_DATA_ERROR。如果解压的是gzip,strm->adler是crc32校验,而不是adler32
返回值:
三、压缩生成文件
#include <stdio.h>
#include "zlib.h"
int main()
{
char *data = "this is a gzip test from NinGoo.net";
gzFile *fp=NULL;
fp=gzopen("test_out.gz","wb");
gzwrite(fp,data,strlen(data));
gzclose(fp);
}
四、内存解压缩
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <zlib.h>
/* Compress data */
int zcompress(Bytef *data, uLong ndata,
Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;
if(data && ndata > 0)
{
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
if(deflateInit(&c_stream, Z_DEFAULT_COMPRESSION) != Z_OK) return -1;
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while (c_stream.avail_in != 0 && c_stream.total_out < *nzdata)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for (;;) {
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(deflateEnd(&c_stream) != Z_OK) return -1;
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}
/* Compress gzip data */
int gzcompress(Bytef *data, uLong ndata,
Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;
if(data && ndata > 0)
{
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
/*-MAX_WBITS*/MAX_WBITS+16, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while (c_stream.avail_in != 0 && c_stream.total_out < *nzdata)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for (;;) {
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(deflateEnd(&c_stream) != Z_OK) return -1;
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}
/* Uncompress data */
int zdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream; /* decompression stream */
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit(&d_stream) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}
/* HTTP gzip decompress */
int httpgzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}
/* Uncompress gzip data */
int gzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, -MAX_WBITS) != Z_OK) return -1;
//if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}
#define BUF_SIZE 65535
int main()
{
char *data = "kjdalkfjdflkjdlkfjdklfjdlkfjlkdjflkdjflddajfkdjfkdfaskf;ldsfk;ldakf;ldskfl;dskf;ld";
uLong ndata = strlen(data);
Bytef zdata[BUF_SIZE];
uLong nzdata = BUF_SIZE;
Bytef odata[BUF_SIZE];
uLong nodata = BUF_SIZE;
memset(zdata, 0, BUF_SIZE);
//if(zcompress((Bytef *)data, ndata, zdata, &nzdata) == 0)
if(gzcompress((Bytef *)data, ndata, zdata, &nzdata) == 0)
{
fprintf(stdout, "nzdata:%d %s\n", nzdata, zdata);
memset(odata, 0, BUF_SIZE);
//if(zdecompress(zdata, ndata, odata, &nodata) == 0)
if(gzdecompress(zdata, ndata, odata, &nodata) == 0)
{
fprintf(stdout, "%d %s\n", nodata, odata);
}
}
}
注windowBits:
-MAX_WBITS 不生成gz头
MAX_WBITS+16 生成gz头
C#代码
/// <summary>
/// 压缩数据流
/// </summary>
/// <param name="buffer"></param>
/// <param name="encode"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string GZipCompress(string buffer, System.Text.Encoding encode)
{
string strs = "";
try
{
if (buffer != null && buffer.Length > 0)
{
byte[] temp = encode.GetBytes(buffer);
using (MemoryStream msTemp = new MemoryStream())
{
using (GZipStream gz = new GZipStream(msTemp, CompressionMode.Compress, true))
{
gz.Write(temp, 0, temp.Length);
gz.Close();
}
msTemp.Seek(0, SeekOrigin.Begin);
msTemp.Flush();
temp = new byte[msTemp.Length];
msTemp.Read(temp, 0, (int)msTemp.Length);
strs = HexToStr(temp);
}
}
}
catch
{
}
return strs;
}
/// <summary>
/// 解压
/// </summary>
/// <param name="str_buffer"></param>
/// <param name="encode"></param>
/// <returns></returns>
public static string GZipDecompress(string str_buffer, System.Text.Encoding encode)
{
try
{
byte[] buffer = StrToHex(str_buffer);
if (buffer.Length > 0)
{
byte[] temp;
using (MemoryStream msTemp = new MemoryStream(buffer))
{
using (MemoryStream msOutTemp = new MemoryStream())
{
using (GZipStream gz = new GZipStream(msTemp, CompressionMode.Decompress, true))
{
gz.CopyTo(msOutTemp);
}
msOutTemp.Seek(0, SeekOrigin.Begin);
msOutTemp.Flush();
temp = new byte[msOutTemp.Length];
msOutTemp.Read(temp, 0, temp.Length);
}
return encode.GetString(temp, 0, temp.Length);
}
}
else
{
return "";
}
}
catch (Exception ex)
{
string s = ex.Message;
return "";
}
}