13

フォルダーとそのすべてのサブフォルダーを再帰的に削除しようとしていますが、まったく機能していません。コードを確認して、ここで何が間違っているのか教えてください。

Windows XPでD7を介してこのコードを実行しています

if FindFirst (FolderPath + '\*', faAnyFile, f) = 0 then
      try             
         repeat

            if (f.Attr and faDirectory) <> 0 then
              begin
                    if (f.Name <> '.') and (f.Name <> '..') then
                      begin                            
                        RemoveDir(FolderPath +'\'+ f.Name);
                      end
                    else
                      begin
                        //Call function recursively...
                        ClearFolder(FolderPath +'\'+ f.Name, mask, recursive);
                      end;
              end;

         until (FindNext (f) <> 0);
      finally
        SysUtils.FindClose (f)
      end;
end;
4

3 に答える 3

31

この大変な作業をすべて自分で行うのではなく、次を使用しますSHFileOperation

uses
  ShellAPI;

procedure DeleteDirectory(const DirName: string);
var
  FileOp: TSHFileOpStruct;
begin
  FillChar(FileOp, SizeOf(FileOp), 0);
  FileOp.wFunc := FO_DELETE;
  FileOp.pFrom := PChar(DirName+#0);//double zero-terminated
  FileOp.fFlags := FOF_SILENT or FOF_NOERRORUI or FOF_NOCONFIRMATION;
  SHFileOperation(FileOp);
end;

価値があるのは、あなたのコードの問題は、それが決して呼び出さないことDeleteFileです. そのため、ディレクトリが空になることはなく、呼び出しがRemoveDir失敗することもありません。コードにエラー チェックがないことは実際には役に立ちませんが、ファイルを削除するためのコードを追加すると、そのコードはまあまあの形になります。また、再帰にも注意する必要があります。すべての子コンテナーが最初に削除され、次に親コンテナーが削除されていることを確認する必要があります。それを正しく行うには、ある程度のスキルが必要です。基本的なアプローチは次のとおりです。

procedure DeleteDirectory(const Name: string);
var
  F: TSearchRec;
begin
  if FindFirst(Name + '\*', faAnyFile, F) = 0 then begin
    try
      repeat
        if (F.Attr and faDirectory <> 0) then begin
          if (F.Name <> '.') and (F.Name <> '..') then begin
            DeleteDirectory(Name + '\' + F.Name);
          end;
        end else begin
          DeleteFile(Name + '\' + F.Name);
        end;
      until FindNext(F) <> 0;
    finally
      FindClose(F);
    end;
    RemoveDir(Name);
  end;
end;

わかりやすくするためにエラー チェックは省略しましたが、 と の戻り値を確認する必要がDeleteFileありRemoveDirます。

于 2012-08-03T15:38:09.170 に答える
7
procedure DeleteDir(const DirName: string);
var
  Path: string;
  F: TSearchRec;

begin
  Path:= DirName + '\*.*';
  if FindFirst(Path, faAnyFile, F) = 0 then begin
    try
      repeat
        if (F.Attr and faDirectory <> 0) then begin
          if (F.Name <> '.') and (F.Name <> '..') then begin
            DeleteDir(DirName + '\' + F.Name);
          end;
        end
        else
          DeleteFile(DirName + '\' + F.Name);
      until FindNext(F) <> 0;
    finally
      FindClose(F);
    end;
  end;
  RemoveDir(DirName);
end;
于 2012-08-03T16:25:26.750 に答える
0

Delphi 2010 から、次のようないくつかのメソッドを含むユニットのTDirectoryレコードがあります。System.IOUtils

TDirectory.Delete('path_to_dir', True);
于 2021-12-30T10:12:17.967 に答える