2009-02-18 10 views
27

En supposant que j'ai un File f qui représente un répertoire, alors f.delete() ne supprimera le répertoire que s'il est vide. J'ai trouvé un couple de examples en ligne qui utilisent File.listFiles() ou File.list() pour obtenir tous les fichiers dans le répertoire, puis traverse récursivement la structure du répertoire et supprime tous les fichiers. Cependant, comme il est possible de créer des structures de répertoires infiniment récursives (dans Windows et Linux (avec des liens symboliques)), il est possible que les programmes écrits dans ce style ne s'arrêtent jamais. Alors, y a-t-il une meilleure façon d'écrire un tel programme pour qu'il ne tombe pas dans ces pièges? Ai-je besoin de garder la trace de partout où j'ai traversé et de m'assurer de ne pas tourner en rond ou y a-t-il une meilleure façon de faire?Suppression de répertoires non vides en Java

Mise à jour: En réponse à certaines des réponses (merci les gars!) - Je préférerais que le code ne suive pas les liens symboliques et reste dans le répertoire qu'il était censé supprimer. Puis-je me fier à l'implémentation de Commons-IO pour ce faire, même dans le cas de Windows?

Répondre

32

Si vous voulez vraiment que votre suppression de répertoire récursive suive des liens symboliques, alors je ne pense pas qu'il y ait un moyen indépendant de la plate-forme de le faire sans garder trace de tous les répertoires que vous avez parcourus.

Cependant, dans la plupart des cas, je pense que vous voudriez juste supprimer le lien symbolique réel pointant vers le répertoire plutôt que de suivre récursivement le lien symbolique.

Si tel est le comportement souhaité, vous pouvez utiliser la méthode FileUtils.deleteDirectory dans Apache Commons IO.

3

File.getCanonicalPath() vous dira le "vrai" nom du fichier, y compris les liens symboliques résolus. Lorsque vous numérisez, vous tombez sur un répertoire que vous connaissez déjà (car vous les avez stockés dans un Map).

+0

J'aurais pensé que cela ralentirait un peu la suppression récursive. Ne pourriez-vous pas faire un File.getPath(). Equals (File.getCanonicalPath())? –

+0

Je ne suis pas sûr du nombre de répertoires récursifs que vous voulez traiter, mais Map.put() et Map.contains() par répertoire ne vous ralentiront pas. Le code que vous avez suggéré ne vous dirait que quelque part sur votre chemin sont des liens symboliques. Ils peuvent être au-dessus du répertoire que vous voulez supprimer. – Bombe

+2

Honnêtement: vous inquiétez de faire le travail en premier.Seulement si cela fonctionne parfaitement et que vous pouvez mesurer que c'est trop lent (peu importe ce que cela signifie), seulement alors vous commencez à vous soucier des performances. L'optimisation prématurée est si bête que ça me fait mal. Physiquement. – Bombe

0

Si vous pouviez savoir quels fichiers sont des liens symboliques, vous pouvez les ignorer.

Il n'y a malheureusement pas de moyen "propre" de détecter les liens symboliques en Java. Découvrez this solution de contournement Java pure ou this one impliquant le code natif.

7

Essayez Apache Commons IO pour une implémentation testée.

Cependant, je ne pense pas que cela gère le problème de la récurrence infinie.

+2

regardez la source: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?view=markup Vous verrez le deleteDirectory ne suit pas les liens symboliques. – elou

0

Au moins sous MacOSX, la suppression d'un lien symbolique vers un répertoire ne supprime pas le répertoire lui-même et peut donc être supprimé même si le répertoire cible n'est pas vide. Je suppose que cela est vrai pour la plupart des systèmes d'exploitation POSIX. Et pour autant que je sache, les liens sous windows sont aussi juste des fichiers, et peuvent être supprimés en tant que tels à partir d'un programme Java.

Questions connexes