真是要命了,用ShellAPI复制文件好是好,但我不知道怎么样把文件复制的进度和我自己窗体上的ProgressBar关联起来,自己写了个用FileStream拷贝函数,代码如下,但碰到 文件正在被使用时,会跳出错误,不知道该如何解决,请大家帮忙!function TMainForm.StreamCopy(FromFile, ToFile: String): Boolean;
var
  FromStr, ToStr: TFileStream;
  PackSize, CurrentSize: Integer;
  Create, LastAccess, LastWrite: TFileTime;
begin
  PackSize := 4096;//我这里直接定义了复制时的大小,不知道这样行不行?
  FromStr := TFileStream.Create(FromFile, fmOpenRead);
  ProgressBar1.Max := FromStr.Size div PackSize;
  try
    ToStr := TFileStream.Create(ToFile, fmCreate);//如果复制到的文件正在使用的话,这里创建就会除错,而且过程停止,我想如果出错的话,能不能直接跳过?
    try
      CurrentSize := 0;
      repeat
        if FromStr.Size - CurrentSize <= PackSize then
          PackSize := FromStr.Size - CurrentSize;
        ToStr.CopyFrom(FromStr, PackSize);
        Inc(CurrentSize, PackSize);
        ProgressBar1.Position := ProgressBar1.Position + 1;
      until CurrentSize >= FromStr.Size;
      GetFileTime(FromStr.Handle, @Create, @LastAccess, @LastWrite);
      SetFileTime(ToStr.Handle, @Create, @LastAccess, @LastWrite);
      ProgressBar1.Position := 0;
    finally
      ToStr.Free;
    end
  finally
    FromStr.Free;
  end;
  Result := true;
end;

解决方案 »

  1.   

    还有一个比较严重的问题,我在复制文件时,经常碰到这样的情况我在复制代码的最前面有个判断 
    if not DirectoryExists(ToDir) then
      ForceDirectories(ToDir)但在复制文件时,有时候会出现,应该创建的文件夹变成了文件,也就是说,正常情况应该创建一个名叫AA的文件夹,但在复制时却创建了一个名为AA的文件!导致复制出错!只要把文件AA,删除,再进行一次复制,又一切正常,这种情况并不常见,只是偶尔会出现那这样的错误!但我奇怪为什么应该是文件夹的 怎么会变成文件去了,这是为什么??
      

  2.   

    写只前,对目标文件进行读写操作,

    try
    except
    如果抛出异常,就退出,,
      

  3.   

    那如何对目标文件进行读写操作呢??procedure TForm1.Button1Click(Sender: TObject);
    var
      ToFile: File;
    begin
      AssignFile(ToFile,Edit1.Text);
      try
        ReWrite(ToFile,1);
      except
        on EInOutError do
          Showmessage('error');
      end;
    end;我这样试了,但在ReWrite的时候就跳出错误!请问应该怎么写?
      

  4.   

    哎。。自己找到一种方法,贴出来吧!
    function checkfile(filename: string):boolean;
    var;
      AFile: THandle;
    begin
      AFile:= CreateFile(PChar(ToFile), GENERIC_READ or GENERIC_WRITE,
          FILE_SHARE_Read, nil, Open_Existing, FILE_ATTRIBUTE_Normal, 0);
      if AFile = INVALID_HANDLE_VALUE then
        Result := False
      else
        Result := True;
      FileClose(AFile);
    end;
      

  5.   

    function TMainForm.StrCopyFile(FromFile, ToFile: string): Boolean;
    var
      FromStr, ToStr: TFileStream;
      PerSize, CurrentSize: Integer;
      Create, LastAccess, LastWrite: TFileTime;
    begin
      PerSize := 4096;
      FromStr := TFileStream.Create(FromFile, fmOpenRead or fmShareDenyNone);
      ProgressBar1.Position:= 0;
      ProgressBar1.Max := FromStr.Size div PerSize;
      try
        try
          ToStr := TFileStream.Create(ToFile, fmCreate);
        except
          FreeAndNil(FromStr);
          Result:= False;
          Exit;
        end;
        try
          CurrentSize := 0;
          repeat
            if Restoring then
            begin
              if FromStr.Size - CurrentSize <= PerSize then PerSize := FromStr.Size - CurrentSize;
              ToStr.CopyFrom(FromStr, PerSize);
              Inc(CurrentSize, PerSize);
              ProgressBar1.Position:= ProgressBar1.Position + 1;
            end else
            begin
              FreeAndNil(ToStr);
              FreeAndNil(FromStr);
              DeleteFile(ToFile);
              Result:= False;
              Exit;
            end;
            Application.ProcessMessages;
          until CurrentSize >= FromStr.Size;
          GetFileTime(FromStr.Handle, @Create, @LastAccess, @LastWrite);
          SetFileTime(ToStr.Handle, @Create, @LastAccess, @LastWrite);
          Result := True;
        finally
          FreeAndNil(ToStr);
        end;
      finally
        FreeAndNil(FromStr);
      end;
      ProgressBar1.Position := 0;
    end;