发信人: teleme(PassWord) 
整理人: teleme(2001-06-28 19:47:51), 站内信件
 | 
 
 
今天用到压缩文件的问题,找了一些网上的资料,后来发现了delphi自身所带的zlib单元,根据例子稍微改变了一些,使它能够符合所有的格式。
 使用时,需要Zlib.pas和 Zlibconst.pas两个单元文件,这两个文件保存在 Delphi 5.0安装光盘上 \Info\Extras\Zlib目录下,此外,在 Info\Extras\Zlib\Obj目录中还保存了 Zlib.pas单元引用的 Obj文件,把这个目录拷贝到delphi的lib下,即可。
 
 原来提供的例子是抓计算机屏幕,现在改成文件流,适应所有情况。也可以适当的改动比如增加目录压缩和分文件压缩,其实就是在文件流前面增加一部分描述结构就是,不多说。使用 时,还要use zlib单元。
 两个函数如下
 
 procedure CompressIt(var CompressedStream: TMemoryStream; const CompressionLevel: TCompressionLevel);
 // 参数是传递的流和压缩方式
 var
    SourceStream: TCompressionStream;
    DestStream: TMemoryStream;
    Count: int64;  //注意,此处修改了,原来是int
 begin
    //获得流的原始尺寸
    Count := CompressedStream.Size;
    DestStream := TMemoryStream.Create;
    SourceStream := TCompressionStream.Create(CompressionLevel, DestStream);
    try
       //SourceStream中保存着原始的流
       CompressedStream.SaveToStream(SourceStream);
       //将原始流进行压缩, DestStream中保存着压缩后的流
       SourceStream.Free;
       CompressedStream.Clear;
       //写入原始图像的尺寸
       CompressedStream.WriteBuffer(Count, SizeOf(Count));
       //写入经过压缩的流
       CompressedStream.CopyFrom(DestStream, 0);
    finally
       DestStream.Free;
    end;
 end;
 
 
 procedure UnCompressit(const CompressedStream: TMemoryStream; var UnCompressedStream: TMemoryStream);
 //参数    压缩过的流,解压后的流
 var
    SourceStream: TDecompressionStream;
    DestStream: TMemoryStream;
    Buffer: PChar;
    Count: int64;
 begin
    //从被压缩的图像流中读出原始的尺寸
    CompressedStream.ReadBuffer(Count, SizeOf(Count));
    //根据尺寸大小为将要读入的原始流分配内存块
    GetMem(Buffer, Count);
    DestStream := TMemoryStream.Create;
    SourceStream := TDecompressionStream.Create(CompressedStream);
    try
       //将被压缩的流解压缩,然后存入 Buffer内存块中
       SourceStream.ReadBuffer(Buffer^, Count);
       //将原始流保存至 DestStream流中
       DestStream.WriteBuffer(Buffer^, Count);
       DestStream.Position := 0; //复位流指针
       DestStream.Position := length(VER_INFO);
       //从 DestStream流中载入图像流
       UnCompressedStream.LoadFromStream(DestStream);
    finally
       FreeMem(Buffer);
       DestStream.Free;
    end;
 end;
 
 使用的例子如下:
 procedure TForm1.Button5Click(Sender: TObject);
 //把指定文件压缩然后保存为另外一个压缩包,
 //呵呵,我使用的时候是把后缀改成cab,可以唬一些人吧?
 var
    SM: TMemoryStream;
 begin
    if OpenDialog1.Execute then
       begin
          if SaveDialog1.Execute then
             begin
                SM := TMemoryStream.Create;
                try
                   Sm.LoadFromFile(OpenDialog1.FileName);
                   SM.Position := 0;
                   Compressit(sm, clDefault);
                   sm.SaveToFile(SaveDialog1.FileName);
                finally
                   SM.Free;
                end;
             end;
       end;
 end;
 
 procedure TForm1.BitBtn2Click(Sender: TObject);
 //把指定的压缩包解成原来的文件。
 var
    SM, DM: TMemoryStream;
 begin
    if OpenDialog1.Execute then
       begin
          if SaveDialog1.Execute then
             begin
                SM := TMemoryStream.Create;
                DM := TMemoryStream.Create;
                try
                   Sm.LoadFromFile(OpenDialog1.FileName);
                   SM.Position := 0;
                   UnCompressit(sm, dm);
                   dm.Position := 0;
                   dm.SaveToFile(SaveDialog1.FileName);
                finally
                   SM.Free;
                   DM.Free;
                end;
             end;
       end;
 end;
 
  ---- Fire Engine   
 
       | 
 
 
 |