Делфи, удалить папку с содержимым
когда у меня есть подпапка в папке - этот код не удаляет папки... Есть какая-нибудь ошибка?
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;
5 ответов
на вашем месте я бы просто сказал операционной системе удалить папку со всем ее содержимым. Сделайте это, написав (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);
[если вы делаете
ShOp.fFlags := 0;
вместо этого вы получаете хороший диалог подтверждения. Если вы это сделаете
ShOp.fFlags := FOF_NOCONFIRMATION;
вы не получаете диалог подтверждения, но вы получаете индикатор выполнения, если операция длительная. Наконец, если вы добавите FOF_ALLOWUNDO
флаг, вы перемещаете каталог в корзину отходов вместо постоянного удаления он.
ShOp.fFlags := FOF_ALLOWUNDO;
конечно, вы можете комбинировать флаги, как вам нравится:
ShOp.fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO;
не покажет никакого подтверждения (но диалог прогресса, потому что вы не указываете FOF_NO_UI
) и каталог будет перемещен в мусорное ведро и не будет окончательно удален.]
самое простое, что нужно сделать, это позвонить TDirectory.Delete(Dir, True)
.
TDirectory
находится в IOUtils
который является довольно недавним добавлением RTL.
The True
флаг передается Recursive
параметр, который означает, что содержимое каталогов опорожняется перед удалением каталога, что является неотъемлемой частью удаления каталогов.
в комментарии вы говорите нам, что используете Delphi 7, и поэтому это не может быть используемый.
ваш код выглядит нормально. Однако, вы не имеете в виду:
(Result.Attr and faAnyFile <> faDirectory)
Я думаю, вы имеете в виду:
(Result.Attr and faDirectory <> faDirectory)
Я бы, наверное, написать так:
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;
последний раз, когда мне нужно было удалить папку с содержанием я использовал тег JCL:
uses JclFileUtils;
DeleteDirectory(DirToDelete, True);
последний параметр указывает, должны ли файлы идти в корзину или нет, что является приятным бонусом.
чтобы решить исходную проблему-попробуйте следующее:
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;
uses DSiWin32;
DSiDeleteTree(folderName, false);
DSiWin32 является открытым исходным кодом проекта relased с лицензией" использовать, как вы хотите".