Existe-t-il un moyen de supprimer récursivement des répertoires entiers en Java?
Dans le cas normal, il est possible de supprimer un répertoire vide. Cependant, quand il s'agit de supprimer des répertoires entiers avec du contenu, ce n'est plus aussi simple que cela.
Comment supprimez-vous des répertoires entiers avec du contenu en Java?
java
file-io
filesystems
delete-directory
paweloque
la source
la source
Réponses:
Vous devriez vérifier le commun-io d'Apache . Il a une classe FileUtils qui fera ce que vous voulez.
la source
Avec Java 7, nous pouvons enfin le faire avec une détection fiable des liens symboliques. (Je ne considère pas que commons-io d'Apache ait une détection de lien symbolique fiable pour le moment, car il ne gère pas les liens sur Windows créés avec
mklink
.)Par souci d'histoire, voici une réponse pré-Java 7, qui suit les liens symboliques.
la source
foo
avec un lienfoo/link
tel quelink->/
, l'appeldelete(new File(foo))
supprimera autant de votre système de fichiers que votre utilisateur est autorisé à le faire !!Dans Java 7+, vous pouvez utiliser la
Files
classe. Le code est très simple:la source
super.postVisitDirectory(dir, exc);
votrepostVisitDirectory
méthode pour exploser si la marche ne peut pas lister un répertoire.Solution à une ligne (Java8) pour supprimer tous les fichiers et répertoires de manière récursive, y compris le répertoire de départ:
Nous utilisons un comparateur pour l'ordre inversé, sinon File :: delete ne pourra pas supprimer le répertoire éventuellement non vide. Donc, si vous souhaitez conserver les répertoires et supprimer uniquement les fichiers, supprimez simplement le comparateur dans sorted () ou supprimez complètement le tri et ajoutez un filtre de fichiers:
la source
.sorted(Comparator.reverseOrder())
la suggestionComparator::reverseOrder
ne fonctionne pas . Voir: stackoverflow.com/questions/43036611/….sorted((f1, f2) -> f2.compareTo(f1))
comparantf2
avecf1
au lieu def1
avecf2
.Java 7 a ajouté la prise en charge des répertoires de marche avec la gestion des liens symboliques:
Je l'utilise comme solution de rechange aux méthodes spécifiques à la plate-forme (dans ce code non testé ):
(SystemUtils est de Apache Commons Lang . Les processus sont privés mais son comportement devrait être évident.)
la source
Je viens de voir que ma solution est plus ou moins la même que celle d'Erickson, juste emballée comme une méthode statique. Déposez cela quelque part, c'est beaucoup plus léger que d'installer tout Apache Commons pour quelque chose qui (comme vous pouvez le voir) est assez simple.
la source
Une solution avec une pile et sans méthodes récursives:
la source
list*
méthodes de classejava.io.File
. À partir des Javadocs: "Renvoie null si ce chemin d'accès abstrait ne désigne pas un répertoire, ou si une erreur d'E / S se produit." Donc:if (currList.length > 0) {
devientif (null != currList && currList.length > 0) {
Si vous avez Spring, vous pouvez utiliser FileSystemUtils.deleteRecursively :
la source
La goyave avait
Files.deleteRecursively(File)
soutenu jusqu'à la goyave 9 .Depuis Goyave 10 :
Par conséquent, il n'y a pas une telle méthode dans Guava 11 .
la source
Ou si vous souhaitez gérer
IOException
:la source
Files.walk(path).iterator().toSeq.reverse.foreach(Files.delete)
walk
méthode garantit déjà une traversée en profondeur.Collections.reverseOrder()
sorte que votre codefor (Path p : Files.walk(directoryToDelete).sorted(reverseOrder()).toArray(Path[]::new))
suppose qu'il a été importé statiquement.Comparator.reverseOrder
?Files.walk(dir) .sorted(Comparator.reverseOrder()) .toArray(Path[]::new))
la source
la source
f.delete()
sousdeleteDirectory(f)
lèvera NoSuchFileException parce quedeleteDirectory(f)
déjà supprimer ce fichier. Chaque répertoire deviendra un chemin lorsqu'il sera transmisdeleteDirectory(f)
et supprimé parpath.delete()
. Par conséquent, nous n'avons pas besoinf.delete()
dans laif f.isDerectory
section. Donc, supprimez simplementf.delete();
sous deleteDirectory (f) et cela fonctionnera.Deux façons d'échouer avec les liens symboliques et le code ci-dessus ... et je ne connais pas la solution.
Voie # 1
Exécutez ceci pour créer un test:
Ici, vous voyez votre fichier de test et votre répertoire de test:
Exécutez ensuite votre commons-io deleteDirectory (). Il se bloque en disant que le fichier est introuvable. Je ne sais pas ce que font les autres exemples ici. La commande Linux rm supprimerait simplement le lien, et rm -r sur le répertoire le ferait également.
Voie # 2
Exécutez ceci pour créer un test:
Ici, vous voyez votre fichier de test et votre répertoire de test:
Ensuite, exécutez votre commons-io deleteDirectory () ou l'exemple de code que les gens ont publié. Il supprime non seulement le répertoire, mais votre fichier de test qui se trouve en dehors du répertoire en cours de suppression. (Il déréférence implicitement le répertoire et supprime le contenu). rm -r supprimerait uniquement le lien. Vous devez utiliser quelque chose comme ceci, supprimez les fichiers déréférencés: "find -L dirtodelete -type f -exec rm {} \;".
la source
Vous pouvez utiliser:
org.apache.commons.io.FileUtils.deleteQuietly(destFile);
Supprime un fichier, sans jamais lancer d'exception. Si le fichier est un répertoire, supprimez-le ainsi que tous les sous-répertoires. La différence entre File.delete () et cette méthode est la suivante: Un répertoire à supprimer ne doit pas être vide. Aucune exception n'est levée lorsqu'un fichier ou un répertoire ne peut pas être supprimé.
la source
Une solution optimale qui gère les exceptions de manière cohérente avec l'approche qu'une exception levée à partir d'une méthode doit toujours décrire ce que cette méthode essayait (et a échoué) de faire:
la source
Dans les projets hérités, je dois créer du code Java natif. Je crée ce code similaire au code Paulitex. Regarde ça:
Et le test unitaire:
la source
Le code ci-dessous supprime récursivement tout le contenu d'un dossier donné.
la source
Voici une méthode principale de bare bones qui accepte un argument de ligne de commande, vous devrez peut-être ajouter votre propre vérification d'erreur ou l'adapter à votre convenance.
J'espère que ça aide!
la source
Peut-être qu'une solution à ce problème pourrait être de réimplémenter la méthode de suppression de la classe File en utilisant le code de la réponse d'Erickson:
la source
Sans Commons IO et <Java SE 7
la source
Alors que les fichiers peuvent facilement être supprimés à l'aide de file.delete (), les répertoires doivent être vides pour être supprimés. Utilisez la récursivité pour le faire facilement. Par exemple:
la source
J'ai codé cette routine qui a 3 critères de sécurité pour une utilisation plus sûre.
la source
Eh bien, supposons un exemple,
Pour plus d'informations, reportez-vous aux ressources ci-dessous
Supprimer le répertoire
la source
rm -rf
était beaucoup plus performant queFileUtils.deleteDirectory
.Après une analyse comparative approfondie, nous avons constaté que l'utilisation
rm -rf
était plusieurs fois plus rapide que l'utilisationFileUtils.deleteDirectory
.Bien sûr, si vous avez un répertoire petit ou simple, cela n'aura pas d'importance, mais dans notre cas, nous avions plusieurs gigaoctets et des sous-répertoires profondément imbriqués où cela prendrait plus de 10 minutes avec
FileUtils.deleteDirectory
et seulement 1 minute avecrm -rf
.Voici notre implémentation Java approximative pour ce faire:
Cela vaut la peine d'essayer si vous avez affaire à des répertoires volumineux ou complexes.
la source
Guava fournit une seule ligne:
MoreFiles.deleteRecursively()
.Contrairement à de nombreux exemples partagés, il prend en compte les liens symboliques et ne supprime pas (par défaut) les fichiers en dehors du chemin fourni.
la source