各位朋友,想请教一下,代码如下,下面这段代码,有两个BUG
第一个:就是拷贝的时候,进度条不能正常显示,只有当文件拷贝完成之后,进度条就会一下子显示完毕
第二个:有时候,拷贝小的文件,例如只有11M左右的文件,当拷贝文件之后,拷贝出来的文件,会比原来的文件大两倍,变成22M。希望有朋友可以解决小弟的难题 ,万分感谢!!!
procedure TForm1.Button1Click(Sender: TObject);
var
  FromStream, ToStream: TfileStream;
  FSize, Step: Integer;
begin
  FromStream := TFileStream.Create('F:\gho-bak\071231C\07123002.GHS', fmOpenRead);
  ToStream := TFileStream.Create('c:\1\071231_C.mp9', fmCreate);//用FromStream.Size获取源文件的大小
  FSize := FromStream.Size;//指定复制进程条(CopyGauge)每次向前移动的数值Step:  Step := Round(100 / (Round(FSize / 256) + 1));
//将要复制的文件分为若干块,每一块大小为256,依次用ToStream.CopyFrom来复制,
//注意最后一块为不能整分所剩的部分仍然要复制。
//在复制的过程中要使复制进程条(CopyGauge)向前移动
  CopyGauge.Position := 0;
  while FSize >= 256 do
    begin
      ToStream.CopyFrom(FromStream, 256);
      CopyGauge.Position := CopyGauge.Position + Step;
     // self.repaint;
      self.update();
      Application.ProcessMessages;
      FSize := FSize - 256;
    end;//复制不能等分的剩余部分,并使复制进程条变为100%
  ToStream.CopyFrom(FromStream, FSize);
  CopyGauge.Position := 100;
//最后释放资源所占内存
  FromStream.Free;
  ToStream.Free;
end;

解决方案 »

  1.   


    procedure TForm1.Button1Click(Sender: TObject);
    const
      BytesPerStep = 256;
    var
      FromStream, ToStream: TfileStream;
      FSize, Step, Done: Integer;
    begin
      FromStream := TFileStream.Create('F:\gho-bak\071231C\07123002.GHS', fmOpenRead);
      ToStream := TFileStream.Create('c:\1\071231_C.mp9', fmCreate);
      FSize := FromStream.Size;
      Step :=  FSize div BytesPerStep;
      CopyGauge.Position := 0;
      CopyGauge.Refresh;
      Done := 0;
      while FSize >= BytesPerStep do
      begin
        ToStream.CopyFrom(FromStream, BytesPerStep);
        FSize := FSize - BytesPerStep;
        Inc(Done);
        if 100 * Done div Step <> CopyGauge.Position then
        begin
          CopyGauge.Position := 100 * Done div Step;
          CopyGauge.Refresh;
        end;
      end;
      ToStream.CopyFrom(FromStream, FSize);
      CopyGauge.Position := 100;
      CopyGauge.Refresh;  FromStream.Free;
      ToStream.Free;
    end;
      

  2.   

    1楼的办法可行
    这行代码:CopyGauge.Position   :=   CopyGauge.Position   +   Step;
    是多余的,流对象拷贝后指针会自动偏移
      

  3.   

    首先我实验了一下你这个代码:
        1。不会使文件放大
        2。要想实现进度条的话可以把你的以下这句代码:
    Step   :=   Round(100   /   (Round(FSize   /   256)   +   1));
        改为:CopyGauge.Max := FSize div 256 ; Step   := 1;
       就可以了 
       
      

  4.   

    procedure   TForm1.Button1Click(Sender:   TObject); 
    var 
        FromStream,   ToStream:   TfileStream; 
        FSize:   Int64; //************文件比较大时Integer有取值问题
    begin 
        FromStream   :=   TFileStream.Create('F:\gho-bak\071231C\07123002.GHS',   fmOpenRead); 
        ToStream   :=   TFileStream.Create('c:\1\071231_C.mp9',   fmCreate); //用FromStream.Size获取源文件的大小 
        FSize   :=   FromStream.Size; //指定复制进程条(CopyGauge)每次向前移动的数值Step: 
        //****下条语句:当FSize>=256*200时,Step恒为0,所以没有进度显示!!!
        //Step   :=   Round(100   /   (Round(FSize   /   256)   +   1)); 
    //将要复制的文件分为若干块,每一块大小为256,依次用ToStream.CopyFrom来复制, 
    //注意最后一块为不能整分所剩的部分仍然要复制。 
    //在复制的过程中要使复制进程条(CopyGauge)向前移动 
        CopyGauge.Position   :=   0; 
        while   FSize   >=   256   do 
            begin 
                ToStream.CopyFrom(FromStream,   256); 
               // CopyGauge.Position   :=   CopyGauge.Position   +   Step;可以改为:
                 CopyGauge.Position   := 100-round(FSize*100/FromStream.Size);    
              //   self.repaint; 
                self.update(); 
                Application.ProcessMessages; 
                FSize   :=   FSize   -   256; 
            end; //复制不能等分的剩余部分,并使复制进程条变为100% 
        ToStream.CopyFrom(FromStream,   FSize); 
        CopyGauge.Position   :=   100; 
    //最后释放资源所占内存 
        FromStream.Free; 
        ToStream.Free; 
    end;