谁能帮我写一个压缩和解压缩文件的函数?请注明该压缩算法名称?回答就给分!

解决方案 »

  1.   

    在delphi版发的帖子,当然是用delphi写呀,麻烦各位大哥了。
      

  2.   

    我是没有delphi的
    都是c的
      

  3.   

    注:其中Progress是TfrmMain上的一个ProgressBar,Status是一个StatusBar const 
      FileHead: string[8]='Huffman'#0; 
      HeadSize=8; 
      BufCount=$FFFF; type 
      TCode=array[0..255]of Byte; 
      TNodeCode=record 
        Ascii: Byte; 
        Code: TCode; 
      end; procedure TfrmMain.Compress (SName, TName: string); 
    type 
      PNode=^TNode; 
      TNode=record 
        Ascii, Code: Byte; 
        Num: Integer; 
        Left, Right, Father: PNode; 
        CodeStr: TCode; 
      end; 
    var 
      SFile, TFile: file; 
      Buf: array[1..BufCount]of Byte; 
      Size, Wrote: Integer; 
      Appears: array[0..255]of Integer; 
      NodeNum: SmallInt; 
      Nodes: array[1..256]of PNode; 
      CodeNum: SmallInt; 
      Codes: array[1..256]of TNodeCode; 
      AscCodes: array[0..255]of TCode; 
      I, J, ReadByte: Integer; 
      P: PNode; 
      {Varibles below are used for WriteBit} 
      Bits, CurByte: Byte; 
      OutBuf: array[1..BufCount]of Byte; 
      BitsSize: Word;   procedure BuildCode (P: PNode); 
      begin 
        if P=nil then Exit; 
        with P^ do 
         begin 
           CodeStr:= Father^.CodeStr; 
           Inc (CodeStr[0]); 
           CodeStr[CodeStr[0]]:= Code; 
         end; 
        if P^.Left=nil then 
         begin 
           Inc (CodeNum); 
           Codes[CodeNum].Code:= P^.CodeStr; 
           Codes[CodeNum].Ascii:= P^.Ascii; 
           Exit; 
         end; 
        BuildCode (P^.Left); 
        BuildCode (P^.Right); 
      end;   procedure FreeTree (P: PNode); 
      var 
        R: PNode; 
      begin 
        if P=nil then Exit; 
        R:= P^.Left; 
        FreeTree (R); 
        R:= P^.Right; 
        FreeTree (R); 
        Dispose (P); 
      end;   procedure WriteBit (Bit: Byte); 
      var 
        Temp: Byte; 
      begin 
        Dec (Bits); 
        Temp:= Bit shl Bits; 
        CurByte:= CurByte or Temp; 
        if Bits=0 then 
         begin 
           Bits:= 8; 
           Inc (BitsSize); 
           OutBuf[BitsSize]:= CurByte;                   
           CurByte:= 0; 
           if BitsSize=BufCount then 
            begin 
              BlockWrite (TFile, OutBuf, BitsSize); 
              BitsSize:= 0; 
              FillChar (OutBuf, SizeOf(OutBuf), 0); 
            end; 
         end; 
      end;   procedure FlushBit; 
      begin 
        if (Bits=8) and (BitsSize=0) then Exit; 
        if Bits<>8 then 
         begin 
           Inc (BitsSize); 
           OutBuf[BitsSize]:= CurByte; 
         end; 
        BlockWrite (TFile, OutBuf, BitsSize); 
        Bits:= 8; 
        CurByte:= 0; 
        BitsSize:= 0; 
        FillChar (OutBuf, SizeOf(OutBuf), 0); 
      end; begin 
      Canceled:= False; 
      Bits:= 8; 
      CurByte:= 0; 
      BitsSize:= 0; 
      FillChar (OutBuf, SizeOf(OutBuf), 0);   btnCancel.Enabled:= True; 
      AssignFile (SFile, SName); 
      AssignFile (TFile, TName); 
      Status.SimpleText:= '正在扫描输入文件...'; 
      Reset (SFile, 1); 
      FillChar (Appears, SizeOf(Appears), 0); 
      while not Eof(SFile) do 
       begin 
         BlockRead (SFile, Buf, BufCount, ReadByte); 
         for I:= 1 to ReadByte do Inc (Appears[Buf[I]]); 
       end; 
      CloseFile (SFile); 
      Status.SimpleText:= '正在生成哈夫曼树...'; 
      NodeNum:= 0; 
      FillChar (Nodes, SizeOf(Nodes), 0); 
      for I:=0 to 255 do 
        if Appears[I]>0 then 
         begin 
           New (P); 
           with P^ do 
            begin 
              Ascii:= I; 
              Code:= 2; 
              Num:= Appears[I]; 
              Left:= nil; 
              Right:= nil; 
              Father:= nil; 
              FillChar (CodeStr, SizeOf(CodeStr), 0); 
            end; 
           J:= 1; 
           while (J<=NodeNum) and (Nodes[J]^.Num>=P^.Num) do Inc (J); 
           Inc (NodeNum); 
           Move (Nodes[J], Nodes[J+1], (NodeNum-J)*SizeOf(Nodes[J])); 
           Nodes[J]:= P; 
         end; 
      if NodeNum=1 then Nodes[1]^.Code:=0; 
      while NodeNum>1 do 
       begin 
         New (P); 
         with P^ do 
          begin 
            Num:= 0; 
            Ascii:= 0; 
            Code:= 2; 
            Left:= nil; 
            Right:= nil; 
            Father:= nil; 
            FillChar (CodeStr, SizeOf(CodeStr), 0); 
          end; 
         P^.Right:=Nodes[NodeNum]; 
         Nodes[NodeNum]^.Father:= P; 
         Nodes[NodeNum]^.Code:= 1; 
         Inc (P^.Num, Nodes[NodeNum]^.Num); 
         Dec (NodeNum); 
         P^.Left:=Nodes[NodeNum]; 
         Nodes[NodeNum]^.Father:= P; 
         Nodes[NodeNum]^.Code:= 0; 
         Inc (P^.Num, Nodes[NodeNum]^.Num); 
         J:= NodeNum; 
         while (J>=2) and (Nodes[J-1]^.Num<=P^.Num) do Dec (J); 
    Move (Nodes[J], Nodes[J+1], (NodeNum-J)*SizeOf(Nodes[J])); 
    Nodes[J]:= P; 
    end; 
    CodeNum:= 0; 
    if Nodes[1]<>nil then 
        if Nodes[1]^.Left=nil 
         then 
          begin 
            CodeNum:= 1; 
            with Codes[1] do 
             begin 
               Ascii:= Nodes[1]^.Ascii; 
               FillChar (Code, SizeOf(Code), 0); 
               Code[0]:=1; 
             end; 
          end 
         else 
          begin 
            BuildCode (Nodes[1]^.Left); 
            BuildCode (Nodes[1]^.Right); 
          end; 
      FreeTree (Nodes[1]); 
      FillChar (AscCodes, SizeOf(AscCodes), 0); 
      for I:= 1 to CodeNum do 
        with Codes[I] do 
          AscCodes[Ascii]:= Code;   Status.SimpleText:= '正在写输出文件...'; 
      Reset (SFile, 1); 
      Rewrite (TFile, 1); 
      BlockWrite (TFile, FileHead[1], HeadSize); 
      BlockWrite (TFile, CodeNum, SizeOf(CodeNum)); 
      for I:= 1 to CodeNum do 
        with Codes[I] do 
         begin 
           BlockWrite (TFile, Ascii, SizeOf(Ascii)); 
           BlockWrite (TFile, Code[0], SizeOf(Code[0])); 
           for J:= 1 to Code[0] do WriteBit (Code[J]); 
           FlushBit; 
         end;   Size:= FileSize(SFile); 
      BlockWrite (TFile, Size, SizeOf(Size));       
      Wrote:= 0; 
      Progress.Min:= 0; 
      Progress.Max:= Size; 
      while not Eof(SFile) do 
       begin 
         BlockRead (SFile, Buf, BufCount, ReadByte); 
         for I:= 1 to ReadByte do 
           for J:= 1 to AscCodes[Buf[I], 0] do 
             WriteBit (AscCodes[Buf[I], J]); 
         Inc (Wrote, ReadByte); 
         Progress.Position:= Wrote; 
       end; 
      FlushBit; 
      CloseFile (TFile); 
      CloseFile (SFile);   Status.SimpleText:= '完成'; 
      btnCancel.Enabled:= False; 
    end;
      

  4.   

    Delphi下有一个zlib库,可以对数据进行压缩,格式类似于zip,这里有一段解压的smaple,压缩类似。uses
      ...,ZLib;function TFormMain.PlaySnd():Boolean;
    //&sup2;&yen;·&Aring;×&Ecirc;&Ocirc;&acute;&Ouml;&ETH;&micro;&Auml;Midi&Ograve;&ocirc;&Agrave;&Ouml;
    var
    ResStream:TResourceStream;
      CpsBuf,DCpsBuf:Pointer;
      DeCompressSize:Integer;
    begin
    Result:=false;
    try
       ResStream:=TResourceStream.Create(hInstance,'Sound','Compress');
    GetMem(CpsBuf,ResStream.Size);
        ResStream.ReadBuffer(CpsBuf^,ResStream.Size);
        DecompressBuf(CpsBuf,ResStream.Size,0,DCpsBuf,DeCompressSize);
        if (PlaySound(DCpsBuf,hInstance,SND_ASYNC or SND_LOOP or SND_MEMORY)=true) then
         Result:=true;
      finally
       ResStream.Free;
      end;
    end;
      

  5.   

    这么麻烦,干吗不用VCLZIP组件,ZIP格式不更好?还是兼容WinZIP的/ by LY http://www.99898.com/www/lysoft
      

  6.   

    呵呵,ZLib,藏在Delphi光盘中的宝贝,俺已经充分利用它了。好东东,经过大量测试比较,发现它的压缩率介于WinZIP和WinACE之间(当然是WinZIP的平均压缩率最小)。利用ZLib可以充分体现个性化,只需做小小的改动就可以实现对备份文件的安全加密,俺已经在几个项目中用过了,完全达到预期效果。
    VCLZIP,听说也是好东东,不过俺没有全面研究过,就不便多说了。