综合

img LuckyJan

数据压缩 -- 应用

发表于2004/10/9 11:15:00  1293人阅读

例:多个目录下多个文件压缩到一个文件;
    对压缩文件解压到个对应目录。
   //压缩文件流: 文件名长度 + 文件名 + 文件长度 + 压缩流
  
uses Lh5Unit.pas;   //见  数据压缩 -- 源码

procedure Compress;
var
  fOutStr: TFileStream;                                  //压缩文件流 

  function doOneFile(srcFile:string):boolean;            //把一个文件压缩到 压缩文件流
  var fInStr: TFileStream;
      fTmp:TmemoryStream;
      fnLen,sz:integer;
  begin
    result:=true;
    if not fileExists(srcFile) then exit;
    try
      fInStr := TFileStream.Create(srcFile,fmOpenRead);
      fTmp   := TmemoryStream.create;
      try
        //在目标流 插入文件名长度 ,文件名,文件长度
        fnLen :=length(srcFile);
        fOutStr.Write(fnLen,sizeof(integer));      //文件名长度       // 或 sizeof(I)
        fOutStr.Write(pFileName[1],fnLen);         //文件名
        LHACompress(fInStr, fTmp);                 //压缩文件 到 TmemoryStream
        sz:=fTmp.Size ;
        fOutStr.Write(sz,sizeof(integer));         //文件压缩长度
        fOutStr.write(fTmp.Memory^,sz);             //压缩流
      finally
        fInStr.Free;
        fTmp.free;
      end;
    except
      result:=false;
    end;
  end;

var
  lhFile,aFileName:string;
begin
  result:=true;
  try
    lhFile:=ExtractFilePath(application.ExeName)+'filePack.LHZ';  //压缩文件名
    if fileExists(lhFile) then DeleteFile(lhFile);

    fOutStr := TFileStream.Create(lhFile,fmCreate);
    try
        .....  //检索要压缩的文件列表
        openSQL('select HtmFile from FAQ where Flags=1 order by HtmFile',data.tbLHZ);

        while not data.tbLHZ.eof do
        begin
          aFileName:='FAQfile/'+data.tbLHZ.FieldByname('HtmFile').asString+'.html';
          if not doOneFile(ExtractFilePath(application.ExeName)+aFileName,aFileName) then
          begin
            result:=false;  //压缩不成功
            break;
          end;
          data.tbLHZ.next;
        end;     
    finally
      fOutStr.Free;
    end;
  except
    result:=false;  //压缩不成功
  end;
end;

function Expand(lhFile:string): boolean;
var
  Src_f:Tfilestream;

  function getOneFile(aFileLen:integer;tFileName:string):boolean;
  var
      dst_f:Tfilestream;
      Mem_f:TmemoryStream;
  begin
    result:=true;
    try 
      if fileExists(tFileName) then deletefile(aFile); //已存在,覆盖它

      dst_f := Tfilestream.create(aFile,fmcreate or fmopenwrite);
      Mem_f := TmemoryStream.create;
      try
        if Mem_f.CopyFrom(src_f,aFileLen)<>aFileLen then raiselastWin32Error; //获取压缩流
        Mem_f.position := 0;

        LHAExpand(Mem_f,dst_f);                    //解压

      finally
        dst_f.free;
        Mem_f.free;
      end;
    except
      result:=false;
    end;
  end;

var
   aFileName:string;
   fnlen,fSize:integer;
begin
  if not fileExists(lhFile) then exit; //压缩文件不存在!  filePack.LHZ

  result:=true;
  try
  src_f := TFileStream.Create(lhFile,fmOpenRead);
  //从临时文件中分离出所有文件的实体
  //src_f 源文件流:  文件名长度 + 文件名 + 文件压缩长度 + 压缩流(被压文件)
  try
    src_f.position := 0;
    while true do begin
      if src_f.size <=src_f.position+1 then break;           //(2.0)如果 iRtn<=0 则文件流读取结束
                                                 
      if src_f.Read(fnlen,sizeof(integer))<=0 then break;    //(2.1)取得文件名长度
      setLength(aFileName,fnlen);                
      if src_f.Read(aFileName[1],fnlen)<=0 then break;       //(2.2)取得文件名
                                                 
      if src_f.Read(fSize,sizeof(integer))<=0 then break;    //(2.3)取得压缩长度

      if getOneFile(fSize,aFileName) then                    //(2.4)获取压缩文件
      begin                                      
        frmMsg.moMsgs.lines.add(aFileName+' 解压缩成功!');  frmMsg.Update ;
      end else
      begin
        frmMsg.moMsgs.lines.add(aFileName+' 解压缩不成功!');  frmMsg.Update ;
      end;
    end; 
  finally
    src_f.free;
  end;
  except
    result:=false;
  end;
end;

阅读全文
0 0

相关文章推荐

img
取 消
img