Delphi,删除带内容的文件夹

Emi*_*Emi 10 windows delphi delphi-7

当我在文件夹中有子文件夹时 - 此代码不是删除文件夹...是否有任何错误?

procedure TForm.Remove(Dir: String);
var
  Result: TSearchRec; Found: Boolean;
begin
  Found := False;
  if FindFirst(Dir + '\*', faAnyFile, Result) = 0 then
    while not Found do begin
      if (Result.Attr and faDirectory = faDirectory) AND (Result.Name <> '.') AND (Result.Name <> '..') then Remove(Dir + '\' + Result.Name)
      else if (Result.Attr and faAnyFile <> faDirectory) then DeleteFile(Dir + '\' + Result.Name);
      Found := FindNext(Result) <> 0;
    end;
  FindClose(Result); RemoveDir(Dir);
end;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 29

最简单的事情是打电话TDirectory.Delete(Dir, True).

TDirectory发现IOUtils其中最近的RTL添加.

True标志被传递给Recursive参数,这意味着在删除目录之前会删除目录的内容,这是删除目录的重要部分.


在评论中,您告诉我们您使用Delphi 7,因此无法使用.

你的代码看起来很好.但是,你不是说:

(Result.Attr and faAnyFile <> faDirectory)
Run Code Online (Sandbox Code Playgroud)

我想你的意思是:

(Result.Attr and faDirectory <> faDirectory)
Run Code Online (Sandbox Code Playgroud)

我可能会写如下:

procedure TMyForm.Remove(const Dir: string);
var
  Result: TSearchRec;
begin
  if FindFirst(Dir + '\*', faAnyFile, Result) = 0 then
  begin
    Try
      repeat
        if (Result.Attr and faDirectory) = faDirectory then
        begin
          if (Result.Name <> '.') and (Result.Name <> '..') then
            Remove(Dir + '\' + Result.Name)
        end
        else if not DeleteFile(Dir + '\' + Result.Name) then
          RaiseLastOSError;
      until FindNext(Result) <> 0;
    Finally
      FindClose(Result);
    End;
  end;
  if not RemoveDir(Dir) then
    RaiseLastOSError;
end;
Run Code Online (Sandbox Code Playgroud)

  • 请不要大写"End","Try"和"Finally"! (7认同)

And*_*and 27

如果我是你,我只是告诉操作系统删除包含其所有内容的文件夹.通过写(uses ShellAPI)这样做

var
  ShOp: TSHFileOpStruct;
begin
  ShOp.Wnd := Self.Handle;
  ShOp.wFunc := FO_DELETE;
  ShOp.pFrom := PChar('C:\Users\Andreas Rejbrand\Desktop\Test\'#0);
  ShOp.pTo := nil;
  ShOp.fFlags := FOF_NO_UI;
  SHFileOperation(ShOp);
Run Code Online (Sandbox Code Playgroud)

[如果你这样做

  ShOp.fFlags := 0;
Run Code Online (Sandbox Code Playgroud)

相反,你得到一个很好的确认对话框.如果你这样做

ShOp.fFlags := FOF_NOCONFIRMATION;
Run Code Online (Sandbox Code Playgroud)

你没有得到确认对话框,但如果操作很长,你会得到一个进度条.最后,如果添加FOF_ALLOWUNDO标记,则将目录移动到废物箱而不是永久删除它.

ShOp.fFlags := FOF_ALLOWUNDO;
Run Code Online (Sandbox Code Playgroud)

当然,您可以根据需要组合标志:

ShOp.fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO;
Run Code Online (Sandbox Code Playgroud)

将不会显示任何确认(但由于您未指定FOF_NO_UI,因此会显示进度对话框),并且该目录将被移动到垃圾箱而不会被永久删除.

  • @大卫:根据[文档](http://msdn.microsoft.com/en-us/library/bb762164(VS.85)的.aspx)时,`pFrom`字符串必须倍加空终止.据我所知,如果没有添加"#0",它只能保证以单个空字符结尾. (3认同)
  • @David:[SHFIleOperation](http://msdn.microsoft.com/en-us/library/bb759795%28v=VS.85%29.aspx)期望一个双重空终止的文件或文件夹列表.PChar演员提供第一个; 连接提供了第二个. (3认同)
  • 使用操作系统进行工作的+1 ...虽然我会根据我删除文件夹的原因指定"无用户界面",因此在情况需要时可以提出标准确认.例如,当它不适合回收站时,或者有子文件夹需要额外的权限等. (2认同)
  • FWIW 这种方法不适用于服务,仅适用于桌面应用程序,而且速度可能非常慢。 (2认同)

Hei*_*cht 9

我最后一次需要删除包含内容的文件夹我使用了JCL:

uses JclFileUtils;

DeleteDirectory(DirToDelete, True);
Run Code Online (Sandbox Code Playgroud)

最后一个参数告诉文件是否应该转到回收站,这是一个很好的奖励.


Rem*_*eau 5

要解决原始问题 - 试试这个:

procedure TForm.Remove(const Dir: String);
var
  sDir: String;
  Rec: TSearchRec;
begin
  sDir := IncludeTrailingPathDelimiter(Dir);
  if FindFirst(sDir + '*.*', faAnyFile, Rec) = 0 then
  try
    repeat
      if (Rec.Attr and faDirectory) = faDirectory then
      begin
        if (Rec.Name <> '.') and (Rec.Name <> '..') then
          Remove(sDir + Rec.Name);
      end else
      begin
        DeleteFile(sDir + Rec.Name);
      end;
    until FindNext(Rec) <> 0;
  finally
    FindClose(Rec);
  end;
  RemoveDir(sDir);
end; 
Run Code Online (Sandbox Code Playgroud)