定制安卓平板刷系统无法安装应用

数据压缩需求讨论及ZLIB库的封装实现(附源码和测试程序)
一、这里的压缩主要用于数据库保存的数据和网络传输的数据进行快速压缩和解压缩。所以最重要的参数是压缩和解压缩的速度。特别是在服务器端。有一这个压缩和上一篇博客讨论的加解密一样将用在整个框架系统的方方面面,因此,必须符合以下条件:
完全开源的并自由使用
支持各种平台和开发语言
符合这个要求的似乎只有Zlib库了(当然也可以自己写,但这完全没必要,且工作量太大了。上篇博客的加解密只是c、delphi、java、JavaScript
这4种语言的实现就已经把我累的要死了)。具体下载可以到
网站下载库文件现在和查阅相关
二、delphi xe2 下的封装
适合Delphixe2 或 xe3的 pas文件下载(系统自带的版本较低):
封装源代码:
{ ******************************************************* }
{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
{ Borland Delphi Visual Component
Library&&&&&&&&&&&&&&&&
{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
{ Copyright (c)
Software&&&&&&&&&&&&&
{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
{ Writed by
白忙剩人&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
{ 适用delphiXe3&
,更新完毕&&& beysky
{ ******************************************************* }
{$I besky.inc}
& System.SysUtils, System.Classes, System.Math,
System.StrUtils,
& Besky.StrUtils, Besky.SysUtils, Besky.Types,
Besky.Consts, ZLibEx;
//{$IFDEF Delphi12}
System.ZL&&&
//系统自带的版本较低
//ZLib_2009, ZlibC
//{$ENDIF}
// Compresshead='BeySky ';
& BeskyCompressKind = (BCKNone, BCKZlib, BCKZip,
BCK7Zip, BCKBZip2, BCKRar, BCKLhz); // 压缩类型
& BeskyCompressBlock = (BCBK_4M, BCBK_8M,
BCBK_16M, BCBK_32M, BCBK_64M);
& PBeskyComPressHead = ^BeskyComPressH
& BeskyComPressHead = record
&&& insize:
&&& outsize:
& { ----压缩&和解压缩 内存---------}
function CompressBuff(inbuff: insize: int32; out outbuff:
out outsize: int32;
& level: TZCompressionLevel = zcDefault):
function D_CompressBuff(inbuff: insize: int32; out
outbuff: out outsize: int32; outEstimate: int32 = 0):
{-------------字符串---------}
function CompressStrToBuff(s: out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function CompressStrToBuff(s: out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function CompressStrToBuff(s: RawB out outbuff:
out outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function CompressStrToBuff(s: W out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function CompressStrToBuff(s: P out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function CompressStrToBuff(s: P out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
outEstimate: int32 = 0): int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
outEstimate: int32 = 0): int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
W outEstimate: int32 = 0): int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
RawB outEstimate: int32 = 0): int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
P outEstimate: int32 = 0): int32;
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
P outEstimate: int32 = 0): int32;
{-------------Tbytes--------}
function CompressToBytes(s: TB level: TZCompressionLevel =
zcDefault): TB
function CompressToBytes(s: level: TZCompressionLevel =
zcDefault): TB
function CompressToBytes(s: level: TZCompressionLevel =
zcDefault): TB
function CompressToBytes(s: W level: TZCompressionLevel =
zcDefault): TB
function CompressToBytes(s: RawB level:
TZCompressionLevel = zcDefault): TB
function CompressToBytes(s: P level: TZCompressionLevel =
zcDefault): TB
function CompressToBytes(s: P level: TZCompressionLevel =
zcDefault): TB
function D_CompressOfBytes(Bts: TB out OutBts: TBytes): int32;
function D_CompressOfBytes(Bts: TB out s: string): int32;
function D_CompressOfBytes(Bts: TB out s: ansistring): int32;
function D_CompressOfBytes(Bts: TB out s: Widestring): int32;
function D_CompressOfBytes(Bts: TB out s: RawBytestring):
function D_CompressOfBytes(Bts: TB out s: Pchar): int32;
function D_CompressOfBytes(Bts: TB out s: Pansichar): int32;
{-----TMemorystream------}
function CompressMemoryStream(ms_in: TMemoryS ms_out:
TMemoryStream = level: TZCompressionLevel = zcDefault):
function D_CompressMemoryStream(ms_in: TMemoryS ms_out:
TMemoryStream = nil): int32;
{--------Tstream--------}
function CompressStream(ss: TS insize: int64; sd: TS
out outsize: int64; level: TZCompressionLevel = zcD
& BuffBlock: BeskyCompressBlock = BCBK_16M):
function D_CompressStream(ss: TS insize: int64; sd: TS
out outsize: int64): int64;
{--------file--------}
function CompressFile(ss: sd: string = ''; level:
TZCompressionLevel = zcD
& BuffBlock: BeskyCompressBlock = BCBK_16M):
function D_CompressFile(ss: sd: string = ''): int64;
implementation
function CompressBuff(inbuff: insize: int32; out outbuff:
out outsize: int32;
& level: TZCompressionLevel = zcDefault):
ZCompress(inbuff, insize, outbuff, outsize, level);
&&& Result :=
Exception do Result := -Abs(E.HelpContext);
function D_CompressBuff(inbuff: insize: int32; out
outbuff: out outsize: int32; outEstimate: int32 = 0):
ZDecompress(inbuff, insize, outbuff, outsize, outEstimate);
&&& Result :=
Exception do Result := -Abs(E.HelpContext);
function CompressStrToBuff(s: out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(@s[1], strsize(s),
outbuff, outsize, level);
function CompressStrToBuff(s: out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(@s[1], strsize(s),
outbuff, outsize, level);
function CompressStrToBuff(s: RawB out outbuff:
out outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(@s[1], strsize(s),
outbuff, outsize, level);
function CompressStrToBuff(s: W out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(@s[1], strsize(s),
outbuff, outsize, level);
function CompressStrToBuff(s: P out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(s, strsize(s),
outbuff, outsize, level);
function CompressStrToBuff(s: P out outbuff: out
outsize: int32; level: TZCompressionLevel = zcDefault)
& : int32;
& if s = '' then Result := -1
& else Result := CompressBuff(s, strsize(s),
outbuff, outsize, level);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
&&& if Result
&&& SetLength(s,
outs div StringElementSize(s));
&&& Move(outp^,
s[1], outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
&&& if Result
&&& SetLength(s,
outs div StringElementSize(s));
&&& Move(outp^,
s[1], outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
W outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
&&& if Result
&&& SetLength(s,
outs div StringElementSize(s));
&&& Move(outp^,
s[1], outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
RawB outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
&&& if Result
&&& SetLength(s,
outs div StringElementSize(s));
&&& Move(outp^,
s[1], outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
P outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
&&& if Result
&&& getmem(s,
outs + StringElementSize(s));
&&& s[outs] :=
&&& Move(outp^,
s^, outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressStrOfBuff(inbuff: insize: int32; out s:
P outEstimate: int32 = 0): int32;
& outs: int32;
& Result := -1;
& if (inbuff = nil) or (insize &=
&&& Result :=
D_CompressBuff(inbuff, insize, outp, outs, outEstimate);
SetLength(st, outs div StringElementSize(st));
&&& Move(outp^,
st[1], outs);
&&& getmem(s,
outs + StringElementSize(s));
&&& StrPLCopy(s,
st, outs);
&&& if Result
FreeMem(outp, outs);
SetLength(st, 0);
function CompressToBytes(s: TB level: TZCompressionLevel =
zcDefault): TB
& outs: int32;
& errcount: int32;
& insize: int32;
& Result :=
& errcount := -1;
& insize := High(s) + 1;
& if insize &= 0
&&& errcount :=
CompressBuff(s, insize, outp, outs, level);
&&& if errcount
SetLength(Result, outs + sizeof(insize));
&&& Move(insize,
Result[0], sizeof(insize));
&&& Move(outp^,
Result[sizeof(insize)], outs);
&&& if errcount
& 0 then FreeMem(outp, outs);
function CompressToBytes(s: level: TZCompressionLevel =
zcDefault): TB
& Result :=
& if s = ''
& Bts := BytesOf(s);
&&& Result :=
CompressToBytes(Bts, level);
High(Result) & 0 then SetLength(Bts, 0);
function CompressToBytes(s: level: TZCompressionLevel =
zcDefault): TB
& Result :=
& if s = ''
& Bts := BytesOf(s);
&&& Result :=
CompressToBytes(Bts, level);
High(Result) & 0 then SetLength(Bts, 0);
function CompressToBytes(s: W level: TZCompressionLevel =
zcDefault): TB
& Result :=
& if s = ''
& Bts := BytesOf(s);
&&& Result :=
CompressToBytes(Bts, level);
High(Result) & 0 then SetLength(Bts, 0);
function CompressToBytes(s: RawB level:
TZCompressionLevel = zcDefault): TB
& Result :=
& if s = ''
& Bts := BytesOf(s);
&&& Result :=
CompressToBytes(Bts, level);
High(Result) & 0 then SetLength(Bts, 0);
function CompressToBytes(s: P level: TZCompressionLevel =
zcDefault): TB
& Result :=
& if (s = '') or (s = nil)
& st := WideCharToString(s);
& Result := CompressToBytes(st, level);
function CompressToBytes(s: P level: TZCompressionLevel =
zcDefault): TB
& Result :=
& if (s = '') or (s = nil)
& Bts := BytesOf(s);
&&& Result :=
CompressToBytes(Bts, level);
High(Result) & 0 then SetLength(Bts, 0);
function D_CompressOfBytes(Bts: TB out OutBts: TBytes): int32;
& inp, outp:
& ins, outs: int32;
& PEstimate: P
& Result := -1;
& ins := High(Bts) + 1 - sizeof(int32);
& if ins &= 0
& PEstimate := Pinteger(Bts);
& inp := ChangePointer(Bts, sizeof(int32));
&&& Result :=
D_CompressBuff(inp, ins, outp, outs, PEstimate^);
&&& if Result
SetLength(OutBts, outs);
&&& Move(outp^,
OutBts[0], outs);
&&& if Result
& 0 then FreeMem(outp, outs);
function D_CompressOfBytes(Bts: TB out s: string): int32;
& OutBts: TB
& Result := -1;
& if High(Bts) &= 0 then
&&& Result :=
D_CompressOfBytes(Bts, OutBts);
&&& if Result
StringOf(OutBts);
&&& if Result
& 0 then SetLength(OutBts, 0);
function D_CompressOfBytes(Bts: TB out s: ansistring): int32;
& OutBts: TB
& Result := -1;
& if High(Bts) &= 0 then
&&& Result :=
D_CompressOfBytes(Bts, OutBts);
&&& if Result
StringOf(OutBts);
&&& if Result
& 0 then SetLength(OutBts, 0);
function D_CompressOfBytes(Bts: TB out s: Widestring): int32;
& OutBts: TB
& Result := -1;
& if High(Bts) &= 0 then
&&& Result :=
D_CompressOfBytes(Bts, OutBts);
&&& if Result
StringOf(OutBts);
&&& if Result
& 0 then SetLength(OutBts, 0);
function D_CompressOfBytes(Bts: TB out s: RawBytestring):
& OutBts: TB
& Result := -1;
& if High(Bts) &= 0 then
&&& Result :=
D_CompressOfBytes(Bts, OutBts);
&&& if Result
StringOf(OutBts);
&&& if Result
& 0 then SetLength(OutBts, 0);
function D_CompressOfBytes(Bts: TB out s: Pchar): int32;
& size: int32;
& Result := -1;
& if High(Bts) &= 0 then
& Result := D_CompressOfBytes(Bts, st);
& if Result &= 0
& size := strsize(st);
& getmem(s, size + StringElementSize(s));
& s := StrPLCopy(s, st, size);
& //& s :=
StringToWideChar(st);
function D_CompressOfBytes(Bts: TB out s: Pansichar): int32;
& OutBts: TB
& Result := -1;
& if High(Bts) &= 0 then
&&& Result :=
D_CompressOfBytes(Bts, OutBts);
&&& if Result
&&& getmem(s,
Result + StringElementSize(s));
&&& s[Result] :=
Move(OutBts[0], s[0], Result);
&&& if Result
& 0 then SetLength(OutBts, 0);
function CompressMemoryStream(ms_in: TMemoryS ms_out:
TMemoryStream = level: TZCompressionLevel = zcDefault):
& outsize, insize: int32;
& Result := -1;
& if not Assigned(ms_in)
& ms_in.Position := 0;
& insize := ms_in.
&&& Result :=
CompressBuff(ms_in.Memory, insize, outp, outsize, level);
&&& if Result
&&& if ms_out =
ms_in.Write(insize, sizeof(int32)); //写入源size
ms_in.Write(outp^, outsize);
ms_out.Write(insize, sizeof(int32));
ms_out.Write(outp^, outsize);
&&& if Result
& 0 then FreeMem(outp, outsize);
function D_CompressMemoryStream(ms_in: TMemoryS ms_out:
TMemoryStream = nil): int32;
& outsize, EstimateSize: int32;
& Result := -1;
& if not Assigned(ms_in)
& ms_in.Position := 0;
& ms_in.Read(EstimateSize, sizeof(int32));
&&& Result :=
D_CompressBuff(ChangePointer(ms_in.Memory, sizeof(int32)),
ms_in.size - sizeof(int32), outp, outsize, EstimateSize);
&&& if Result
&&& if ms_out =
ms_in.Write(outp^, outsize);
ms_out.Write(outp^, outsize);
&&& if Result
& 0 then FreeMem(outp, outsize);
function CompressStream(ss: TS insize: int64; sd: TS
out outsize: int64; level: TZCompressionLevel = zcD
& BuffBlock: BeskyCompressBlock = BCBK_16M):
& BlockSize: int32;
& inp, outp:
& ins, outs: int32;
& remainedSize: int64;
& errcount: int32;
& head: BeskyComPressH
& Result := -1;
& if (not Assigned(ss)) or (ss.size = 0) then
& if not Assigned(sd)
& errcount := -1;
& outsize := 0;
& case BuffBlock of
&&& BCBK_4M:
BlockSize := 4194304;
&&& BCBK_8M:
BlockSize := 8388608;
&&& BCBK_16M:
BlockSize := ;
&&& BCBK_32M:
BlockSize := ;
&&& BCBK_64M:
BlockSize := ;
& else BlockSize := ;
& getmem(inp, BlockSize);
&&& outsize :=
outsize + sd.Write(BuffBlock, sizeof(BeskyCompressBlock));
//写入buffblock类型
&&& if insize
& ss.size - ss.Position then remainedSize := ss.size
- ss.Position
remainedSize :=
&&& repeat
ins := ss.Read(inp^, BlockSize);
remainedSize := remainedSize -
errcount := CompressBuff(inp, ins, outp, outs, level);
if errcount &= 0 then exit(errcount); //压缩失败退出
head.insize :=
head.outsize :=
outsize := outsize + sd.Write(head, sizeof(head));
if outs & ins then outsize := outsize +
sd.Write(outp^, outs) //写入压缩后内容
else outsize := outsize + sd.Write(inp^, ins)
//若压缩后size变大则写入未压缩的内容
if errcount & 0 then FreeMem(outp, outs);
(remainedSize &= 0) or (ss.Position
&= ss.size);
&&& Result :=
&&& FreeMem(inp,
BlockSize);
function D_CompressStream(ss: TS insize: int64; sd: TS
out outsize: int64): int64;
& Blocktype: BeskyCompressB
& BlockSize: int32;
& inp, outp:
& ins, outs: int32;
& remainedSize: int64;
& errcount: int32;
& head: BeskyComPressH
& Result := -1;
& if (not Assigned(ss)) or (ss.size = 0) then
& if not Assigned(sd)
& Result := -1;
& errcount := -1;
& outsize := 0;
& ss.Read(Blocktype, sizeof(Blocktype));
& case Blocktype of
&&& BCBK_4M:
BlockSize := 4194304;
&&& BCBK_8M:
BlockSize := 8388608;
&&& BCBK_16M:
BlockSize := ;
&&& BCBK_32M:
BlockSize := ;
&&& BCBK_64M:
BlockSize := ;
& getmem(inp, BlockSize);
&&& if insize
& ss.size - ss.Position then remainedSize := ss.size
- ss.Position
remainedSize :=
&&& repeat
remainedSize := remainedSize - ss.Read(head, sizeof(head));
//读取压缩头
if head.insize &= head.outsize then
//压缩后size变大则读取压缩前的size
ins := ss.Read(inp^, head.insize);
outsize := outsize + sd.Write(inp^, ins);
ins := ss.Read(inp^, head.outsize);
errcount := D_CompressBuff(inp, ins, outp, outs,
head.insize);
if errcount &= 0 then exit(errcount);
outsize := outsize + sd.Write(outp^, outs);
if errcount & 0 then FreeMem(outp, outs);
remainedSize := remainedSize -
(remainedSize &= 0) or (ss.Position
&= ss.size);
&&& Result :=
&&& FreeMem(inp,
BlockSize);
function CompressFile(ss: sd: string = ''; level:
TZCompressionLevel = zcD
& BuffBlock: BeskyCompressBlock = BCBK_16M):
& fss, fsd: TF
& outsize: int64;
& Result := -1;
& if not FileExists(ss)
//输入文件不存在则退出
&&& fss :=
TFilestream.Create(ss, fmOpenRead, fmShareDenyWrite);
//压缩时只读并拒绝写入方式打开文件
&&& fss.Position
&&& if sd = ''
then sd := ChangFileNameExt(ss, '.bygz');
//若输出文件名为空则为原文件名+.encry
&&& fsd :=
TFilestream.Create(sd, fmCreate, fmShareExclusive);
//独占方式创建输出文件
&&& fsd.Position
dataSaveToStream(ExtractFileName(ss), fsd); //保存原文件名
Result := CompressStream(fss, fss.size, fsd, outsize, level,
BuffBlock);
FreeAndNil(fss);
FreeAndNil(fsd);
Exception do Result := -Abs(E.HelpContext);
function D_CompressFile(ss: sd: string = ''): int64;
& fss, fsd: TF
& outsize: int64;
& Result := -1; //解密错误!';
& if not FileExists(ss)
&&& fss :=
TFilestream.Create(ss, fmOpenRead, fmShareDenyWrite);
&&& fss.Position
dataLoadFromStream(fname, fss) &&
&&& if sd = ''
then sd := ExtractFilePath(ss) +
&&& fsd :=
TFilestream.Create(sd, fmCreate, fmShareExclusive);
&&& fsd.Position
Result := D_CompressStream(fss, fss.size - fss.Position, fsd,
FreeAndNil(fss);
FreeAndNil(fsd);
Exception do Result := -Abs(E.HelpContext);
测试程序下载:
三、常用压缩软件的测试和评价
zlib自带封装和本人封装文件压缩比较
居然我封装文件压缩函数比其本身自带饿标准Gz文件压缩和解压缩快,且压缩率几乎一样(都采用default压缩),我封装的文件解压基本上只受限于我5400转硬盘速度了.
来看看rar 和7z 以及rar的zip 压缩情况.
结论是7z压缩率最高,速度最慢,慢了几倍
解压缩和其他比满的更多.zip最快,但rar是多线程压缩,我封装的函数暂时只用到了单线程一个cpu(双核),所以cpu占用压缩时在40~50%左右.而rar和7z几乎都是85~95%占用,因此估计采用多线程后,zlib瓶颈依然是磁盘IO能力.而且多种文件测试,压缩率高低各软件基本上都在10%以内.在硬盘和网络速度越来越快的今天,感觉7z没多大存在的必要,rar也没啥优势了.总的说来还是zip效率更高.
四、下一篇博客讨论和研究多线程和线程池的实现.之后改写这个简单文件压缩为多线程文件夹压缩,再来测试一下,我相信应该会有最好的性能,比zip都好.
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。7726人阅读
开源库探索系列(9)
&&& 本文整理自zlib.net以及zlib 1.2.7的手册页http://zlib.net/manual.html。
&& &zlib是一套免费、通用、法律上不受限制的无损数据压缩库,可以在任何硬件及操作系统上使用。zlib数据格式可以跨平台移植。不像Unix compress(1)和GIF图像格式中使用的LZW压缩方法,当前zlib中使用的压缩算法不会扩充数据(LZW在极端情况下能使文件大小变为原来2 倍或3倍)。zlib的内存印迹也独立于输入数据,并且在压缩时能够被减小。zlib由Jean-loup Gailly与Mark Adler所开发,初版0.9版在日发表。zlib使用抽象化的DEFLATE算法,最初是为libpng函数库所写的,后来普遍为许多软件所使用。此函数库为自由软件,使用zlib授权。
&& &zlib授权是一个自由软件授权协议,但并非copyleft。协议原文在http://www.gzip.org/zlib /zlib_license.html。最新版本为1.2.2,日发布。版权持有人为Jean-loup Gailly和Mark Adler(),类似于BSD许可。任何人都可以使用本软件,用于任何目的,包括闭源的商业应用。源码的修改和重新分发都是自由的,除了必须注明来源,并在发布的软件中保留此授权协议副本。
&& &1、当前版本
#define ZLIB_VERSION &1.2.7&
#define ZLIB_VERNUM 0x1270
&& &2、功能特性
&& &zlib压缩库提供内存内压缩/解压缩函数。包括对解压数据完整性检查。这个版本只支持一种压缩方式(deflation),但是以后其他的算法也会被加入进来,并且保持同样的流接口。如果缓存区足够大,压缩被一次完成(例如输入文件被mmap了),否则就重复调用压缩。在后一种情况,程序必须在每次调用时提供更多的输入或更多输出空间。
&& &本压缩库使用的默认压缩数据格式为zlib格式(在RFC 1950中描述),它是对deflate流(在RFC 1951中描述)的一种封装。本压缩库也支持对gzip(.gz)格式文件的读写操作,操作接口以&gz&开头,和stdio相似。gzip格式与 zlib格式不同,在RFC 1952中描述,是对deflate流的另一种封装。
&& &本压缩库不安装任何信号处理器,解码器检查压缩数据的一致性,所以,即使在有损坏的输入情况下,本压缩库也不会崩溃。
&& &(1)数据头
&& &zlib能使用gzip数据头(header)、zlib数据头或者不使用数据头压缩数据。通常情况下,数据压缩使用zlib数据头,因为这提供错误数据检测。当数据不使用数据头写入时,结果是没有任何错误检测的原始DEFLATE数据,那么解压缩软件的调用者知道压缩数据在什么地方结束。
&& &gzip数据头比zlib数据头要大,因为它保存了文件名和其他文件系统信息,事实上这是广泛使用的gzip文件的数据头格式。注意zlib函式库本身不能创建一个gzip文件,但是它能够相当轻松的通过把压缩数据写入到一个有gzip文件头的文件中。
&& &(2)算法
&& &目前zlib仅支持一个LZ77的变种算法,即DEFLATE的算法。这个算法使用很少的系统资源,对各种数据提供很好的压缩效果。这也是在ZIP档案中无一例外的使用这个算法。(尽管zip文件格式也支持几种其他的算法)。看起来zlib格式将不会被扩展使用任何其他算法,尽管数据头可以有这种可能性。
&& &(3)使用资源
&& &函式库提供了对处理器和内存使用控制的能力。不同的压缩级别数值可以指示不同的压缩执行速度。还有内存控制管理的功能。这在一些诸如嵌入式系统这样内存有限制的环境中是有用的。
&& &(4)策略
&& &压缩可以针对特定类型的数据进行优化。若使用者总是使用zlib压缩特定类型的数据,那么可以使用有针对性的策略可以提高压缩效率和性能。例如,如果使用者的数据包含很长的重复数据,那么可以用RLE(运行长度编码)策略,可能会有更好的结果。对于一般的数据,默认的策略是首选。
&& &(5)错误处理
&& &错误可以被发现和跳过,数据混乱可以被检测(只要数据和zlib或者gzip数据头一起被写入)。此外,如果全刷新点(full-flush points)被写入到压缩后的数据流中,那么错误数据是可以被跳过的,并且解压缩将重新同步到下个全刷新点(错误数据的无错恢复被提供)。全刷新点技术对于在不可靠的通道上的大数据流是很有用的,一些过去的数据丢失是不重要的(例如多媒体数据),但是建立太多的全刷新点会极大的影响速度和压缩。
&& &(6)数据长度
&& &对于压缩和解压缩,没有数据长度的限制。重复调用库函数允许处理无限的数据块。一些辅助代码(计数变量)可能会溢出,但是不影响实际的压缩和解压缩。当压缩一个长(无限)数据流时,最好写入全刷新点。
&& &(7)使用zlib的软件
&& &今天,zlib是一种事实上的业界标准,以至于在标准文档中,zlib和DEFLATE常常互换使用。数以千计的应用程序直接或间接依靠zlib压缩函式库(参考http://zlib.net/apps.html),包括:
&&& Linux核心:使用zlib以实作网络协定的压缩、档案系统的压缩以及开机时解压缩自身的核心。
&&& libpng,用于PNG图形格式的一个实现,对bitmap数据规定了DEFLATE作为流压缩方法。
&&& Apache:使用zlib实作http 1.1。
&&& OpenSSH、OpenSSL:以zlib达到最佳化加密网络传输。
&&& FFmpeg:以zlib读写Matroska等以DEFLATE算法压缩的多媒体串流格式。
&&& rsync:以zlib最佳化远端同步时的传输。
&&& Subversion 、Git和 CVS等版本控制系统:使用zlib来压缩和远端仓库的通讯流量。
&&& dpkg和RPM等包管理软件:以zlib解压缩RPM或者其他封包。
&& &另外,zlib被用在很多其他的编程语言中。在Java中可通过java.utl.zip使用zlib库;Python中通过import zlib使用zlib库;Perl的zlib接口可在CPAN找到;Tcl的zlib接口参看http://wiki.tcl.tk/4610。因为其代码的可移植性,宽松的授权许可以及较小的内存占用,zlib在许多嵌入式设备中也有应用。&& &
&& &3、流数据结构
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
typedef void
(*free_func)
OF((voidpf opaque, voidpf address));
struct internal_
typedef struct z_stream_s {
z_const Bytef *next_
/* 下一个输入字节 */
/* next_in中可用的字节数 */
/* 目前读取的输入总字节数 */
*next_ /* 下一个输出字节应该放在这 */
avail_ /* next_out中剩下的可用空间 */
total_ /* 目前输出的总字节数 */
z_const char *
/* 最后的错误消息,如果没错误为NULL */
struct internal_state FAR * /* 对应用程序不可见 */
/* 用来分配内部状态 */
/* 用来释放内部状态 */
/* 传给zalloc和zfree的私有数据对象 */
/* 数据类型的最好猜测:二进制数据或文本 */
/* 解压数据的adler32值 */
/* 保留为将来使用 */
typedef z_stream FAR *z_
/* 来自或传给zlib例程的gzip头部信息,对这些字段的含义,参考RFC 1952 */
typedef struct gz_header_s {
/* 为true,如果压缩数据被认为是文本 */
/* 修改时间 */
/* 额外标志(写gzip文件时不会用到) */
/* 操作系统 */
/* 指向额外的字段,如果没有则为Z_NULL */
/* 额外字段的长度(如果extrextra != Z_NULL则有底) */
/* extra的空间上限(只用在读头部) */
/* 指向以0终止的文件名,或为Z_NULL */
/* name的空间上限(只用在读头部) */
/* 指向以0终止的注释,或为Z_NULL */
/* comment的空间上限(只用在读头部) */
/* 为true,如果会有头部CRC */
/* 为true,当gzip头部读取完时(写gzip文件时不会用到) */
typedef gz_header FAR *gz_&&& 当avail_in变成0时,应用程序必须更新next_int和avail_in。当avail_out变成0时,还必须更新next_out和 avail_out。应用程序在调用init函数之前必须初始化zalloc,zfree和opaque。除此,其他的所有被压缩库设置的字段都不能被应用程序修改。应用程序提供的opaque值将作为调用时传给zalloc和zfree的第一个参数,这在用户内存管理里有用。opaque值对压缩库本身并没有什么意义。如果对象没有足够的内存,zalloc必须返回Z_NULL。如果zlib被用在多线程环境中,zalloc和zfree必须是线程安全的。
&& &在16-bit系统上,函数zalloc和zfree必须能够分配精确的65536字节,但如果定义了符号MAXSEG_64K(参看 zconf.h),则并不需要分配比这更多的空间。在MSDOS上,zalloc返回的65536字节对象的指针必须把偏移规格化为0,默认的分配函数会保证这一点(参看zutil.c)。为了减少内存需求,并且避免64K对象的分配,可以带-DMAX_WBITS=14编译参数(参看zconf.h)来编译zlib库,这样会牺牲一点压缩率。
&& &字段total_in和total_out可用于统计和进程报告。在压缩后,total_in表示解压数据总大小,它可以被解压工具使用,特别是如果解压工具想一步之内解压所有的数据。
&& &4、常量/* 允许的flush值,更多细节参看下面的deflate()和inflate() */
#define Z_NO_FLUSH
#define Z_PARTIAL_FLUSH 1
#define Z_SYNC_FLUSH
#define Z_FULL_FLUSH
#define Z_FINISH
#define Z_BLOCK
#define Z_TREES
/* 压缩、解压函数的返回码,负数表示错误,正数表示正常事件 */
#define Z_OK
#define Z_STREAM_END
#define Z_NEED_DICT
#define Z_ERRNO
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR
#define Z_MEM_ERROR
#define Z_BUF_ERROR
#define Z_VERSION_ERROR (-6)
/* 压缩级别 */
#define Z_NO_COMPRESSION
#define Z_BEST_SPEED
#define Z_BEST_COMPRESSION
#define Z_DEFAULT_COMPRESSION
/* 压缩策略,细节参看下面的deflateInit2() */
#define Z_FILTERED
#define Z_HUFFMAN_ONLY
#define Z_RLE
#define Z_FIXED
#define Z_DEFAULT_STRATEGY
/* data_type字段可能的值(参看inflate()) */
#define Z_BINARY
#define Z_TEXT
#define Z_ASCII
/* 为了兼容1.2.2和更早的版本 */
#define Z_UNKNOWN
/* deflate压缩方式(这个版本支持的唯一压缩方式) */
#define Z_DEFLATED
define Z_NULL
/* 为了初始化zalloc, zfree, opaque */
/* 为了兼容小于1.0.2的版本 */
#define zlib_version zlibVersion()&&& 5、基本函数
&& &(1)ZEXTERN const char * ZEXPORT zlibVersion OF((void));
&& &应用程序会比较zlibVersion和ZLIB_VERSION的一致性。如果第一个字不同,说明zlib和应用程序使用的zlib.h是不一致的。这个检查将被defalteInit和infalteInit自动调用。
&& &(2)ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
&& &为压缩初始化内部流的状态。字段zalloc, zfree和opaque必须在调用之前初始化。如果zalloc和zfree被设为Z_NULL,deflateInit用默认分配函数来更新它们。压缩级别必须是define Z_DEFAULT_COMPRESSION,或者0到9之间,1为最快速度,9为最好的压缩率,0表示不作任何压缩(输入数据简单地被拷贝成一块)。 Z_DEFAULT_COMPRESSION为默认压缩级别,它在速度和压缩率之间取一个折衷(当前等于级别6)。函数成功时返回Z_OK,否则返回相应的错误码(Z_MEM_ERROR,
Z_STREAM_ERROR或Z_VERSION_ERROR)。deflateInit不执行任何压缩动作,压缩动作由deflate()来执行。
&& &(3)ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
&& &压缩尽可能多的数据,直到输入缓冲区变空或输出缓冲区变满。它可能引入一些输出延迟(读取输入但不产生任何输出),除非强制刷新缓冲区。本函数执行以下一个或两个动作:
&& &* 压缩从next_in开始的输入数据,并且更新相应的next_in和avail_in。如果不能处理所有的输入(因为输出缓冲区已满),next_in和avail_in会作相应更新,并且下一次调用deflate()时在这个点处恢复执行。
&& &* 生成从next_out开始的输出,并且更新相应的next_out和avail_out。如果参数flush为非零,则本行为强制执行。强制频繁地刷新会降低压缩率,因此这个参数应该只在必要时才设置(在交互式应用程序中)。有些输出即使flush没有被设置也会生成。
&& &(4)ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
&& &所有为当前流分配的动态数据结构被释放。本函数抛弃任何未处理的输入,并且不会刷新任何挂起的输出。成功时返回Z_OK,流状态不一致时返回 Z_STREAM_ERROR,流过早被释放时(一些输入或输出被抛弃了)返回Z_DATA_ERROR。在错误情形中,msg信息可能被设置,然后指向一个静态字符串。
&& &(5)ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
&& &为解压初始化内部流状态。字段next_in, avail_in, zalloc, zfree和opaque必须在调用之前初始化。如果next_in不等于Z_NULL且avail_in足够大(准确的值取决于压缩方式),inflateInit从zlib头部确定压缩方式,然后分配所有数据结构。否则分配将会被推迟到第一次调用inflate。如果zalloc和 zfree被设为Z_NULL,inflateInit用默认分配函数来更新它们。函数返回 Z_OK,Z_MEM_ERROR,Z_VERSION_ERROR或Z_STREAM_ERROR。
&& &(6)ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
&& &解压尽可能多的数据。直到输入缓冲区变空或输出缓冲区变满。它可能引入一些输出延迟(读取输入但不产生任何输出),除非强制刷新缓冲区。本函数执行以下一个或两个动作:
&& &* 解压从next_in开始的输入数据,并且更新相应的next_in和avail_in。如果不能处理所有的输入(因为输出缓冲区已满),next_in会作相应更新,并且下一次调用inflate()时在这个点处恢复执行。
&& &* 生成从next_out开始的输出,并且更新相应的next_out和avail_out。inflate()生成尽可能多的输出,直到没有更多的输入或者输出缓冲区已满。flush参数可以是Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,Z_BLOCK或Z_TREES。
&& &(7)ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
&& &所有为这个stream动态分派的数据结构在这被释放。 这个函数丢弃所有未处理的输入,并且不会刷新任何挂起的输出。如果成功,inflateEnd返回Z_OK;如果stream是不一致的,返回 Z_STREAM_ERROR,在错误情形中,msg信息可能被设置,然后指向一个静态字符串。
&& &6、高级函数
&& &以下函数用于一些特殊的应用中:
&& &ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int& level, int& method, int& windowBits, int& memLevel, int& strategy));
&& &ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt& dictLength));
&& &ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source));
&& &ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
&& &ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy));
&& &ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain));
&& &ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen));
&& &ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, unsigned *pending, int *bits));
&& &ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value));
&& &ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head));
&& &ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int& windowBits));
&& &ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt& dictLength));
&& &ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
&& &ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source));
&& &ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
&& &ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, int windowBits));
&& &ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value));
&& &ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
&& &ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head));
&& &ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window));
&& &ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc));
&& &ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
&& &ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
&& &7、实用函数
&& &以下实用函数的实现建立在前面介绍的基本面向流的函数上。为了简化接口,设置了一些默认选项(压缩级别,内存使用,标准内存分配器功能)这些实用函数的源代码很容易被修改,如果你要实现一些特殊选项。
&& &(1)ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
&& &压缩source buffer到destination buffer。sourceLen是source buffer的长度(byte)。调用前,destLen是destination buffer的总共长度(byte),它必须至少是compressBound(sourceLen)的返回值,一般为sourceLen长度的0.1% 再加上12个byte。退出前,destLen是实际的compressed buffer长度。如果输入文件是mmap的,这个函数可以一次压缩整个文件。如果压缩成功返回Z_OK,
如果没有足够的内存返回Z_MEM_ERROR,如果输出缓冲区中没有足够的空间返回Z_BUF_ERROR。
&& &(2)ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,&& uLongf *destLen, const Bytef *source, uLong sourceLen, int level));
&& &与compress功能一样,只不过多了一个level参数。参数level为压缩级别,与defalteInit中的含义一样。如果level是无效的,返回Z_STREAM_ERROR。
&& &(3)ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
&& &返回compressed size的上限,在sourceLen个字节上执行copress()或compress2()后。在调用compress()或compress2() 分配destination buffer之前,本函数可用于计算的destLen。
&& &(4)ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,&& uLongf *destLen, const Bytef *source, uLong sourceLen));
&& &解压source buffer到destination buffer。sourceLen是source buffer的长度(byte)。调用前,destLen是destination buffer的总共长度(byte),它必须足够大以容纳全部解压后的数据(解压后的数据大小必须在先前由压缩工具保存好,然后通过一些机制传给解压工具,这种机制不在本压缩库的讨论范围内)。退出前,destLen是实际的compressed buffer长度。如果输入文件是mmap的,这个函数可以一次解压整个文件。如果解压成功返回Z_OK,如果没有足够的内存返回
Z_MEM_ERROR,如果输出缓冲区中没有足够的空间返回Z_BUF_ERROR,如果输入数据有损坏返回Z_DATA_ERROR。在没有足够空间的情况下,uncompress()用解压数据填充输出缓冲区,直到空间末尾为上。&& &
&& &(5)下面是gzip文件访问函数。
&& &typedef struct gzFile_s *gzF&&& /* 半透明的gzip文件描述符 */
&& &ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
&& &打开一个gzip(.gz)文件进行读/写。mode参数和fopen一样(&rb&或& wb&),但也可以包括压缩级别如&wb9&;或者一个策略,如&f&作为过滤数据&wb6f&,&h&是huffman压缩&wb1h&,&R&是行程编码&wb1R&,
&F&是固定编码压缩&wb9F&(关于压缩策略可参看deflateInit2的描述);如果mode为&T&,将指定透明的写或附加操作,没有压缩,也不使用gzip格式。可见gzopen可用于读一个没有gzip格式的文件,这时gzread
直接从没有解压缩的文件中读数据。如果文件不能被打开或是没有足够的内存,gzopen将返回NULL。
&& &ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
&& &用文件描述符来关联一个gzFile。文件描述符可通过open, dup, creat, pipe或fileno(如果文件之前已经用open打开了)之类的调用获取。mode参数与gzopen中类似。
&& &ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
&& &设置本函数库用到内部缓冲区大小。默认大小为8192字节。本函数必须在gopen或gzdopen之后调用,在任何读或写文件之前调用,缓冲区内存分配总是会被推迟第一次读或写文件时。两个缓冲区被分配,要么两个缓冲区都使用这个设置值 ,要么一个使用这个设置值,另一个为这个值的两倍。一个更大的缓冲区大小,如64K或128K字节,将显著加快解压速度(读速度)。gzbuffer成功返回0,失败返回-1,例如调用得太晚。
&& &ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
&& &动态更新压缩级别或策略。参数含义参看deflateInit2的描述。成功返回Z_OK,如果文件没有为写操作而打开,返回Z_STREAM_ERROR。&& &
&& &ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
&& &从压缩文件中读取给定大小的解压字节数。如果输入文件不是gzip格式,gzread直接复制指定定大小的字节数到缓冲区。返回实际读取的字节数,出错则返回-1。
&& &ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
&& &写入给定大小的未解压数据到压缩文件中,返回实际写入的字节数,出错返回0。
&& &ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
&& &在格式字符串的控制下转换、格式化或写入参数到压缩文件,这类似于fprintf。返回实际写入的字节数,出错则返回0。
&& &ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
&& &写入给定的以null终止的字符串到压缩文件,写入时不包括末尾的null字符。返回实际写入的字符数,出错时返回-1。
&& &ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
&& &从压缩文件中读取字节,直到len-1个字符被读取,或者一个换行字符被读取并传给buf,或者一个end-of-file条件被触发。如果各字符都读取完或者len==1,字符串最后将加上null字符。返回buf,如果出错则返回Z_NULL。
&& &ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
&& &写入一个被转换成unsigned char的字符c到压缩文件,返回写入的字符,出错则返回-1。
&& &ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
&& &从压缩文件中读取一个字节,返回这个字节。如果出错或文件到达末尾,返回-1。本函数实现为一个宏,以加快速度。
&& &ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
&& &推回一个字符到原来的流中,这个字符即将在下一次读操作中作为首个被读取的字符。返回这个字符,出错则返回-1。
&& &ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
&& &刷新所有挂起的输出到压缩文件。参数flush与deflate()中类似。返回值为zlib错误码(参看gzerror函数)。
&& &ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence));
&& &设置压缩文件下一次gzread或gzwrite操作的开始位置。
&& &ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
&& &重绕给定的文件,本函数只用于读操作,等价于(int)gzseek(file, 0L, SEEK_SET)。
&& &ZEXTERN int ZEXPORT gzeof OF((gzFile file));
&& &如果end-of-file指示符被设置,返回true(1),否则返回0。
&& &ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
&& &如果读取时内容被直接拷贝到缓冲区,返回1,否则返回0。
&& &ZEXTERN int ZEXPORT gzclose OF((gzFile file));
&& &刷新所有挂起的输出,关闭压缩文件,释放所有的(de)compression状态。注意一旦文件被关闭,不能再调用gzerror,因为所有结构都被释放。在一个文件上不能调用gzclose多次,因为在一次分配上释放操作不能被调用多次。
&& &ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
&& &返回在给定的压缩文件上发生的最后一次错误消息。
&& &ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
&& &清除给定压缩文件的错误消息和end-of-file标志。
&& &8、校验函数
&& &这些函数和压缩是没有关系的,但是被公开是因为在应用序使用本压缩库时,他们可能是有用的。
&& &(1)ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
&& &用字节buf[0...len-1]更新一个运行的Adler-32校验和,返回这个新的CRC-32。如果buf为NULL,返回这个校验和需要的初始值。一个Adler-32校验和作为CRC32几乎是可靠的,但是计算起来更快。使用例子:
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
if (adler != original_adler) error();&&& (2)ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
&& &用字节buf[0...len-1]更新一个运行的CRC-32校验和,返回这个新的校验和。如果buf为NULL,返回这个CRC需要的初始值。使用例子:uLong crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
if (crc != original_crc) error();&&&
9、文件概览
&& &alder32.c:计算数据流的Alder-32校验和,实现alder32()。
&& &crc32.h和crc32.c:计算数据流的CRC-32,实现crc32()。
&& &deflate.h和deflate.c:使用默认算法压缩数据,实现deflate函数簇。
&& &inflate.h和inflate.c:zlib的解压,实现inflate函数簇。
&& &compress.c:实现内存缓冲区的压缩,包括compress(), compress2(), compressBound()。
&& &uncompr.c:实现内存缓冲区的解压,包括uncompress()。
&& &gzguts.h和gzlib.c:读写gzip文件的通用实现,包括gzopen(), gzdopen(), gzbuffer(), gzrewind(), gzseek(), gztell(), gzoffset(), gzeof(), gzerror(), gzclearerr()。
&& &gzclose.c:实现gzclose()。
&& &gzread.c:读取gzip文件的实现,包括gzread(), gzgetc(), gzungetc(), gzgets(), gzdirect(), gzclose_r()。
&& &gzwrite.c:写gzip文件的实现,包括gzwrite(), gzputc(), gzputs(), gzprintf(), gzflush(), gzsetparams(), gzclose_w()。
&& &infback.c:使用回调接口实现解压,包括inflateBackInit(), inflateBack(), inflateBackEnd()。
&& &zutil.h和zutil.c:zlib库用到的工具函数。包括zlibVersion(), zlibCompileFlags(), zError()。
&& &zlib.h:zlib库导出的接口描述文件,应用程序使用zlib库时需要本文件。
&& &zconf.h:zlib库的编译配置文件,如果编译时需要给所有库函数加上唯一的前缀,或者需要针对不同平台作特殊编译,需要用到本文件。还包括标准 C/C++兼容性定义;编译成DLL时是否使用WINAPI/WINAPIV调用方式;类型定义Byte,uInt, uLong, voidpf等。
&& &inftrees.h和inftrees.c:为有效的解码生成Huffman树。&& &
&& &trees.h和trees.c:使用Huffman编码输出压缩的数据。
&& &inffixed.h:使用固定编码压缩。
&& &inffast.h和inffast.c:快速解压数据。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1190442次
积分:13506
积分:13506
排名:第740名
原创:162篇
转载:82篇
译文:70篇
评论:170条
(1)(1)(6)(1)(20)(20)(18)(24)(2)(8)(13)(3)(5)(11)(13)(1)(2)(3)(1)(8)(4)(2)(5)(7)(3)(6)(3)(2)(3)(2)(5)(1)(8)(1)(4)(3)(1)(6)(4)(18)(18)(9)(26)(13)

我要回帖

更多关于 安卓平板刷系统 的文章

 

随机推荐