用zlib压缩、解压缩流、判断是否压缩过了

海宏原创,用zlib压缩、解压缩流、判断是否压缩过了

//流操作:压缩流。源流不是全部压缩了,而是从当前position开始压缩
function CompressStream(oSource, oTarget:TStream; nCount:Int64=-1):integer;     //压缩流
var oZip:TCompressionStream;        oTmp:TMemoryStream;
    iBuf:Pointer;                   niSize:integer;                
begin
    result:=-1;
    try
      try
        niSize:=nCount;           
        if niSize<0 then niSize:=oSource.Size-oSource.Position; //默认为从当前position向后全部
        //if niSize=0 raise exception.Create('源流大小(默认为流体积-流当前位置)为0,非法。');
        oTarget.Position:=0;
        oTmp:=TMemoryStream.Create;
        //暂存
        getMem(iBuf, niSize+1);                       //获取缓冲内存
        oSource.read(iBuf^, niSize);                 //暂存入缓冲区
        oTmp.write(iBuf^, niSize);
        //压缩处理,最大压缩
        oZip:=zlib.TCompressionStream.Create(clMax, oTarget); //参数1是压缩比; 参数2是接收流
        oTmp.SaveToStream(oZip);                      //凡是传入的,都将被压缩
        freeAndNil(oZip);                             //压缩流 Free 后才真正完成压缩, 所以提前 Free
        //完成
        result:=oTarget.Size;
      finally
        if assigned(iBuf) then freeMem(iBuf);         //释放资源
        if assigned(oTmp) then oTmp.Free;
        if assigned(oZip) then oZip.Free;
      end;
    except
      on x:Exception do raise exception.Create('[CompressStream]压缩流出错(源流大小默认为流体积-流当前位置)!'#13+x.Message);
    end;
end;
//流操作:解压缩流
function DecompressStream(oSource, oTarget:TStream; nCount:Int64=-1):integer;   //解压缩流
var //oTmp:TMemoryStream;           oZip:TDeCompressionStream;
    iBuf, oBuf:Pointer;           n, niSize, noEstimate, noSize:Integer;
begin
    try
      try
        niSize:=nCount;           noEstimate:=0;
        if niSize<0 then niSize:=oSource.Size-oSource.Position; //默认为从当前position向后全部
        //if niSize=0 raise exception.Create('源流大小(默认为流体积-流当前位置)为0,非法。');
        //暂存
        getMem(iBuf, niSize+1);                       //获取缓冲内存
        oSource.read(iBuf^, niSize);                  //暂存入缓冲区
        //解压缩:直接解压缩缓冲区,可以返回大小;而用 TDeCompressionStream 必须指定大小
        zlib.DecompressBuf(iBuf, niSize, noEstimate, oBuf, noSize);
        oTarget.Position:=0;
        oTarget.Write(oBuf^, noSize);
        //完成
        result:=oTarget.Size;
      finally
        if assigned(iBuf) then freeMem(iBuf);         //释放资源
        if assigned(oBuf) then freeMem(oBuf);
      end;
    except
      on x:Exception do raise exception.Create('[DecompressStream]解压缩流出错(源流大小默认为流体积-流当前位置)!'#13+x.Message);
    end;
end;

//检查是否已经压缩过了
function TOleContainerStream.getIsZipped:Boolean;
const nZipSign=$DA78;     //直接打开文件发现,zlib压缩后的文件头,都是78DA开头
var nP:Integer;           nSign:Word;                 //smallInt
begin
    nSign:=self.size;
    if nSign<(sizeOf(Header)+sizeOf(nSign)) then
        result:=false
    else begin
        nP:=self.position;
        self.Position:=sizeOf(header);                //检查是否已经压缩过了
        self.Read(nSign, sizeOf(nSign));
        result:=nSign=nZipSign;
        self.position:=nP;
    end;
end;

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值