注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

海宏软件的个人主页

用机器解放人的双手

 
 
 

日志

 
 

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

2009-03-24 20:09:08|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

//流操作:压缩流。源流不是全部压缩了,而是从当前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;

 

  评论这张
 
阅读(1763)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017