Как рекурсивно удалить пустой каталог в Delphi
В родительском каталоге D:\AAA есть 2 дочерних пустых каталога D:\AAA\BB1 и D:\AAA\BB2. Мое требование - как рекурсивно удалить пустой каталог. Вот две функции, найденные в Интернете, как показано ниже: // рекурсивное удаление пустого каталога
function RemoveEmptyDirectory(path: string) : Boolean;
var
MySearch: TSearchRec;
Ended: Boolean;
begin
if FindFirst(path + '\*.*', faDirectory, MySearch) = 0 then
begin
repeat
if ((MySearch.Attr and faDirectory) = faDirectory) and
(MySearch.Name[1] <> '.') then
begin
if DirectoryIsEmpty(path + '\' + MySearch.Name) then
TDirectory.Delete(path + '\' + MySearch.Name)
else
begin
RemoveEmptyDirectory(path + '\' + MySearch.Name);
if DirectoryIsEmpty(path + '\' + MySearch.Name) then
RemoveEmptyDirectory(path + '\' + MySearch.Name);
end;
end;
until FindNext(MySearch) <> 0;
FindClose(MySearch);
end;
end;
// проверяем, пустой каталог или нет
function DirectoryIsEmpty(Directory: string): Boolean;
var
SR: TSearchRec;
i: Integer;
begin
Result := False;
FindFirst(IncludeTrailingPathDelimiter(Directory) + '*', faAnyFile, SR);
for i := 1 to 2 do
if (SR.Name = '.') or (SR.Name = '..') then
Result := FindNext(SR) <> 0;
FindClose(SR);
end;
Моя проблема здесь: при первом запуске функция RemoveEmptyDirectory обнаружит, что D:\AAA не пуст, затем будет запущена отправка (рекурсивно), после удаления 2 дочерних каталогов D:\AAA\BB1 и D:\AAA\BB2, родительский элемент станет пустым каталогом. Вернитесь к первому раунду и поместите функцию DirectoryIsEmpty, чтобы сообщить, что родительский каталог не является пустым!!!! Почему!!!! Система Windows по-прежнему не меняет состояние каталога???
Итак, есть ли хорошее предложение, которое могло бы удовлетворить мои требования.
3 ответа
Вы никогда не проверяете D:\AAA
сам.
Просто сделайте проверку и удаление в конце:
function RemoveEmptyDirectory(path: string) : Boolean;
var
MySearch: TSearchRec;
Ended: Boolean;
begin
if FindFirst(path + '\*.*', faDirectory, MySearch) = 0 then
begin
repeat
if ((MySearch.Attr and faDirectory) = faDirectory) and
(MySearch.Name[1] <> '.') then
begin
if DirectoryIsEmpty(path + '\' + MySearch.Name) then
TDirectory.Delete(path + '\' + MySearch.Name)
else
begin
RemoveEmptyDirectory(path + '\' + MySearch.Name);
if DirectoryIsEmpty(path + '\' + MySearch.Name) then
RemoveEmptyDirectory(path + '\' + MySearch.Name);
end;
end;
until FindNext(MySearch) <> 0;
FindClose(MySearch);
end;
if DirectoryIsEmpty(path) then
TDirectory.Delete(path);
end;
Вы можете использовать TDirectory
как
TDirectory.Delete('D:\AAA', True);
Если вам нужно проверить, пусты ли каталоги или нет, вы можете использовать TDirectory.GetDirectories()
как
Var
S: string;
begin
for S in TDirectory.GetDirectories('D:\AAA', '*', TSearchOption.soAllDirectories) do
begin
if TDirectory.IsEmpty(S) then
TDirectory.Delete(S);
end;
If TDirectory.IsEmpty('D:\AAA') then
TDirectory.Delete('D:\AAA');
Я думаю, что это просто и понятно, и должно подойти, если максимальная производительность не имеет решающего значения:
procedure RemoveEmptyDirs;
var
i,Removed:integer;
Arr:TStringDynArray;
const
TargedDir = 'C:\BunchOfDirs\';
begin
Arr := TDirectory.GetDirectories(TargedDir,'*',TSearchOption.soAllDirectories);
Repeat
Removed := 0;
For i := High(Arr) downto Low(Arr) do begin
If TDirectory.IsEmpty(Arr[i]) then begin
TDirectory.Delete(Arr[i]);
System.Delete(Arr,i,1);
Inc(Removed);
end;
end;
Until Removed = 0;
end;