11
votes

Delphi, suppression dossier avec contenu

Lorsque j'ai le sous-dossier dans le dossier - ce code n'est pas supprimé des dossiers ... y a-t-il une erreur?

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;


4 commentaires

De côté, ce code pourrait être écrit avec une répétition jusqu'à la boucle et éviter ainsi le besoin de la variable locale .


En outre, il est un peu drôle que a trouvé est false si un fichier a été trouvé et true si un fichier n'a pas été trouvé ...


Si l'une des réponses ci-dessous a résolu votre problème, vous devez l'accepter en cliquant sur la coche à gauche de la réponse. Si plus d'une réponse a résolu votre problème, choisissez le «meilleur» à accepter.


Quelques DUPS: Stackoverflow .com / questions / 16336761 / ... , Stackoverflow.com/Questtions/11798783/...


5 Réponses :


30
votes

Si j'étais vous, je voudrais simplement dire au système d'exploitation de supprimer le dossier avec tout son contenu. Le faire en écrivant ( utilise shellapi code>) xxx pré>

[si vous faites p>

ShOp.fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO;


7 commentaires

@Emi: Déclarez ensuite const fof_no_ui = 1556; .


PCHAR ('C: \ Users \ Andreas Rejbrand \ Desktop \ Test \' # 0) est plutôt bizarre. Quel est le problème? Vous écririez pchar (dir) . Mais si vous utilisiez un littéral, vous pouvez simplement écrire shop.pfrom: = 'c: \ utilisateurs \ andreas rejbrand \ bureau \ test \';


@David: selon La documentation , le PFROM La chaîne doit être terminée doublement null. Pour autant que je sache, sans l'ajout de # 0 il est seulement garanti de se terminer par un seul caractère null.


@David: shfileOperation attend un Liste de fichiers ou de dossiers terminés à double null. La distribution Pchaler fournit le premier; La concaténation fournit la seconde.


+1 Pour utiliser le système d'exploitation pour faire le travail ... Bien que je spécifierais «pas d'interface utilisateur» en fonction de la raison pour laquelle je supprimais un dossier, des confirmations standard peuvent donc être soulevées lorsque des circonstances l'exigent. Par exemple, lorsqu'il ne correspond pas à la corbeille de recyclage, ou il y a des sous-dossiers nécessitant des priviligènes supplémentaires, etc.


FWIW Cette méthode ne fonctionnera pas pour les services, uniquement des applications de bureau, et elle peut être très lente.


Ma version de votre code a échoué silencieusement car le pchar () était manquant. THX



32
votes

La chose la plus simple à faire est d'appeler tdirectory.delete (DIR , Vrai) .

tdirectory est trouvé dans ioutils qui est une addition RTL assez récente.

Le drapeau true est transmis au récursif Paramètre, ce qui signifie que le contenu des répertoires est empié avant que le répertoire soit supprimé, une partie essentielle de répertoires de suppression de la suppression.


Dans un commentaire que vous dites que vous utilisez delphi 7 et Donc, cela ne peut pas être utilisé.

Votre code semble très bien. Cependant, vous ne voulez pas dire: xxx

Je pense que vous voulez dire: xxx

je l'écrirais probablement comme suit : xxx


5 commentaires

Veuillez ne pas capitaliser fin , essayer et enfin !


@Andreas il est trop tard! Je fais cela pour les faire se démarquer car ils ont un flux de contrôle non standard. Ils sont comme chic gotos.


Je pense que cette version a un bogue, il essaiera de supprimer un "fichier" avec "". ou ".." en cela. Tout se passe au début manquant.


@Wodzu merci. Vous avez raison. C'est pourquoi je n'abandonnais jamais de code comme celui-ci. À mon lieu de travail, nous utilisons le début / la fin sur tous les blocs.


Heureux d'avoir pu aider, il est très facile de tomber dans ce piège sans commencer / fin :)




4
votes
uses DSiWin32;

DSiDeleteTree(folderName, false);
DSiWin32 is open source project relased with "use as you wish" license.

0 commentaires

5
votes

Pour résoudre le problème d'origine - essayez ceci:

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; 


0 commentaires