procedure TForm1.btn2Click(Sender: TObject);
var
  ds: TDecompressionStream;
  dm, sm: TMemoryStream;
  num: Int64;
begin
  sm := TMemoryStream.Create;
  sm.LoadFromFile('f:\c.zipx');
  sm.Read(num, SizeOf(num));
 
// num读出来后是4977709564142869112
// 文件大小有117M
 
  dm := TMemoryStream.Create;
  dm.SetSize(num);  //运行到这里 out of memory 报错。不支持这么大的文件的原因么??
 
  pb1.Max := Integer(num div 1024);
 
  ds := TDecompressionStream.Create(sm);
  ds.OnProgress := dsProcess;
 
  ds.Read(dm.Memory^, num);
  dm.SaveToFile('f:\d.exe');
 
  dm.Free;
  sm.Free;
  ds.Free;
end;

解决方案 »

  1.   

    LoadFromFile 之后能确定 Position 等于 0 吗?
    你这个 num 是不是也太大了点吧?不像是 117M 的样子。
      

  2.   


    我换用delphi帮助里的方法。。解压矢耦还是报错郁闷啊,data error。
    我压缩一个文件后,这个*.zip打开是空的。这个压缩方法是把文件直接压缩,还是添加到压缩文件里啊?
    还是我写错了??但全是按照帮助的example写的啊
    procedure TForm1.btn1Click(Sender: TObject);
    var
      LZip: TCompressionStream;
      LInput, LOutput: TFileStream;
      Num: Int64;
    begin
      if not dlgSave1.Execute then
        Exit;
      LInput := TFileStream.Create(lst1.Items[lst1.ItemIndex], fmOpenRead);
      try
        Num := LInput.Size;    LOutput := TFileStream.Create(dlgSave1.FileName, fmCreate);
        try
          LOutput.Write(Num, SizeOf(Num));      LZip := TCompressionStream.Create(clMax, LOutput);
          try
            pb1.Max := Integer(Num div 1024);
            LZip.OnProgress := csProcess;
            LZip.CopyFrom(LInput, LInput.Size);
          finally
            LZip.Free;
          end;    finally
          LOutput.Free;
        end;
      finally
        LInput.Free;
      end;
    end;procedure TForm1.btn2Click(Sender: TObject);
    var
      LUnZip: TDecompressionStream;
      LInput, LOutput: TFileStream;
      Num: Int64;
    begin
      if not dlgSave1.Execute then
        Exit;
      LInput := TFileStream.Create(lst1.Items[lst1.ItemIndex], fmOpenRead);
      try
        Num := LInput.Size;    LOutput := TFileStream.Create(dlgSave1.FileName, fmCreate);
        try
          LUnZip := TDecompressionStream.Create(LInput);
          try
    //        pb1.Max := Integer(LInput.Size);
    //        LUnZip.OnProgress := dsProcess;
            LOutput.CopyFrom(LUnZip, 0);
          finally
            LUnZip.Free;
          end;
        finally
          LOutput.Free;
        end;
      finally
        LInput.Free;
      end;
    end;
      

  3.   

    我不是很肯定以下代码是否可用。
    不过,lz 可以借鉴一下。{-------------------------------------------------------------------------------
     单元名: uDuoZlib.pas
     功能  : 简单压缩 -- Zlib
     作者  : Duo
     日期  :2010-04-28 22:04:09
     说明  :压缩解压 流,文件
             字符串压缩使用类方法,如果字符串过短,还是不要压缩的好。反而变大。
    -------------------------------------------------------------------------------}
    unit uDuo.Zlib;interfaceuses SysUtils,Classes,ZLib,Forms;type
      TZlibOnProgressEvent = procedure (AFileSize,AFilePos:Int64) of object;  TZlib=class
      private
        FFilePos: Int64;
        FFileSize: Int64;
        FOnProgress: TZlibOnProgressEvent;
        procedure CsProgress(Sender:TObject); // 压缩
        procedure DsProgress(Sender:TObject); // 解压
      public
        procedure CompressionStream(ASourceStream,ATargetStream:TStream);
        procedure DecompressionStream(ASourceStream,ATargetStream:TStream);
        procedure CompressionFile(const ASourceFile,ATargetFile:TFileName);
        procedure DecompressionFile(const ASourceFile,ATargetFile:TFileName);    // 直接使用的函数,没有进度条
        class function CompressionString(const ASource:string):String;
        class function DecompressionString(const ASource:String):String;    property FileSize:Int64 read FFileSize;
        property FilePos:Int64 read FFilePos;
        property OnProgress:TZlibOnProgressEvent read FOnProgress write FOnProgress;
      end;implementation{ TZlib }procedure TZlib.CompressionFile(const ASourceFile, ATargetFile: TFileName);
    var
      fs,ms:TMemoryStream;
    begin
      fs := TMemoryStream.Create;
      ms := TMemoryStream.Create;
      try
        fs.LoadFromFile(ASourceFile);
        CompressionStream(fs,ms);
        ms.SaveToFile(ATargetFile);
      finally
        ms.Free;
        fs.Free;
      end;
    end;procedure TZlib.CompressionStream(ASourceStream,ATargetStream:TStream);
    var
      cs:TCompressionStream;
    begin
      FFileSize := ASourceStream.Size;
      if FFileSize > 0 then
      begin
        cs := TCompressionStream.Create(clMax,ATargetStream);
        try
          cs.OnProgress := CsProgress;
    //      ASourceStream.Position := 0; // no use ???
          cs.CopyFrom(ASourceStream,0);
        finally
          cs.Free;
        end;
      end;
    end;class function TZlib.CompressionString(const ASource: string): String;
    var
      buffer: Pointer;
      size: Integer;
    begin
      CompressBuf(PChar(ASource),Length(ASource),buffer,size);
      SetLength(Result,size);
      Move(buffer^,Pointer(Result)^,size);
      FreeMem(buffer);
    end;procedure TZlib.CsProgress(Sender: TObject);
    begin
      FFilePos := TCompressionStream(Sender).Position;
      if Assigned(FOnProgress) then
        FOnProgress(FFileSize,FFilePos);
      Application.ProcessMessages;
    end;procedure TZlib.DecompressionFile(const ASourceFile,
      ATargetFile: TFileName);
    var
      fs,ms:TMemoryStream;
    begin
      fs := TMemoryStream.Create;
      ms := TMemoryStream.Create;
      try
        fs.LoadFromFile(ASourceFile);
        DecompressionStream(fs,ms);
        ms.SaveToFile(ATargetFile);
      finally
        ms.Free;
        fs.Free;
      end;
    end;procedure TZlib.DecompressionStream(ASourceStream,ATargetStream:TStream);
    var
      ds:TDecompressionStream;
    begin
      FFileSize := ASourceStream.Size;
      if FFileSize > 0 then
      begin
        ASourceStream.Position := 0;
        ds := TDecompressionStream.Create(ASourceStream);
        try
          ds.OnProgress := DsProgress;
          FFileSize := ATargetStream.CopyFrom(ds,FFileSize);
          ATargetStream.Size := FFileSize;
        finally
          ds.Free;
        end;
      end;
    end;class function TZlib.DecompressionString(const ASource: String): String;
    var
      buffer: Pointer;
      size: Integer;
    begin
      DecompressBuf(PChar(ASource),Length(ASource),0,buffer,size);
      SetLength(Result,size);
      Move(buffer^,Pointer(Result)^,size);
      FreeMem(buffer);
    end;procedure TZlib.DsProgress(Sender: TObject);
    begin
      FFilePos := TDecompressionStream(Sender).Position;
      if Assigned(FOnProgress) then
        FOnProgress(FFileSize,FFilePos);
      Application.ProcessMessages;
    end;end.
      

  4.   

    很是奇怪。为什么我压缩后的*.zip打开后里面是空的
      

  5.   

    仔细检查每一步的 Stream 对象的 Position,是不是没有赋值 0.
    还有,我那段代码能用吗?
    如果能用,你比对一下。