FileExists 后 RenameFile 中的访问被拒绝

问题描述

我经常使用 Delphi 10.2 将文件从路径导入到应用程序中。每次成功导入后,我想将当前文件移动到新路径(Successpath)。 Successpath 中可能已经存在文件名。这就是为什么我首先检查文件名是否存在。如果是这种情况,我会在文件名后附加一个索引(例如 test.txt 更改为 test_2.txt)。

在某些情况下,RenameFile 返回 false,GetLastError 返回拒绝访问。它可能是一个关闭文件句柄。调用 FileExists 后是否需要关闭句柄?我该怎么做?

这是我的示例代码

procedure TDemo.Execute;
begin
  MoveFileWithRenameDuplicates('C:\temp\test.txt','C:\temp\new\');
end;

procedure TDemo.MoveFileWithRenameDuplicates(oldFile,newPath: string);
var
  lNewFile: string;
  i: integer;

begin
  lNewFile := newPath + TPath.GetFileName(oldFile);
  i := 0;
  repeat
    if FileExists(lNewFile) then
    begin
      i := i + 1;
      lNewFile := newPath + TPath.GetFileNameWithoutExtension(oldFile) + '_' + IntToStr(i) + TPath.GetExtension(oldFile);
    end;
  until not FileExists(lNewFile);
  WriteLn('lNewFile=' + lNewFile);

  if not RenameFile(oldFile,lNewFile) then
    WriteLn(SysErrorMessage(GetLastError));
end;

解决方法

我按照 Remy 的建议更改了循环。我还意识到附加的索引实际上并没有增加,所以我也改变了:

procedure TDemo.MoveFileWithRenameDuplicates(oldFile,newPath: string);
var
  lNewFile: string;
  i: integer;
 
begin
    lNewFile := newPath + TPath.GetFileName(oldFile);
    i := 0;
    while not RenameFile(oldFile,lNewFile) do
    begin
        if FileExists(lNewFile) then
        begin
          lNewFile := newPath
            + TRegEx.Match(TPath.GetFileNameWithoutExtension(oldFile),'/^(?''name''[^_]*)_\d*$',[roIgnoreCase]).Groups['name'].Value
            + '_' + IntToStr(i) + TPath.GetExtension(oldFile);
        end
    else
        begin
          WriteLn(SysErrorMessage(GetLastError));
          break;
        end;
    end;
end;

这似乎解决了我的问题。