Verzeichnis rekursiv in Java löschen

1. Einleitung

In diesem Artikel wird veranschaulicht, wie ein Verzeichnis in einfachem Java rekursiv gelöscht wird. Wir werden uns auch einige Alternativen zum Löschen von Verzeichnissen mit externen Bibliotheken ansehen.

2. Verzeichnis rekursiv löschen

Java hat die Option, ein Verzeichnis zu löschen. Dies setzt jedoch voraus, dass das Verzeichnis leer ist. Wir müssen also die Rekursion verwenden, um ein bestimmtes nicht leeres Verzeichnis zu löschen:

  1. Holen Sie sich den gesamten Inhalt des zu löschenden Verzeichnisses
  2. Löschen Sie alle untergeordneten Elemente, die kein Verzeichnis sind (Beenden der Rekursion).
  3. Beginnen Sie für jedes Unterverzeichnis des aktuellen Verzeichnisses mit Schritt 1 (rekursiver Schritt).
  4. Löschen Sie das Verzeichnis

Lassen Sie uns diesen einfachen Algorithmus implementieren:

boolean deleteDirectory(File directoryToBeDeleted) { File[] allContents = directoryToBeDeleted.listFiles(); if (allContents != null) { for (File file : allContents) { deleteDirectory(file); } } return directoryToBeDeleted.delete(); }

Diese Methode kann anhand eines einfachen Testfalls getestet werden:

@Test public void givenDirectory_whenDeletedWithRecursion_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); boolean result = deleteDirectory(pathToBeDeleted.toFile()); assertTrue(result); assertFalse( "Directory still exists", Files.exists(pathToBeDeleted)); }

Die @ Before- Methode unserer Testklasse erstellt einen Verzeichnisbaum mit Unterverzeichnissen und Dateien am Pfad pathToBeDeleted, und die @ After- Methode bereinigt das Verzeichnis bei Bedarf.

Als nächstes schauen wir uns an, wie wir das Löschen mit zwei der am häufigsten verwendeten Bibliotheken erreichen können - Apaches Commons-Io und Spring Frameworks Spring-Core. Mit beiden Bibliotheken können wir die Verzeichnisse mit nur einer einzigen Codezeile löschen.

3. Verwenden von FileUtils von commons-io

Zuerst müssen wir die Commons-Io- Abhängigkeit zum Maven-Projekt hinzufügen :

 commons-io commons-io 2.5 

Die neueste Version der Abhängigkeit finden Sie hier.

Jetzt können wir FileUtils verwenden , um alle dateibasierten Operationen einschließlich deleteDirectory () mit nur einer Anweisung auszuführen :

FileUtils.deleteDirectory(file);

4. Verwenden von FileSystemUtils aus Spring

Alternativ können wir dem Maven-Projekt die Pring-Core- Abhängigkeit hinzufügen :

 org.springframework spring-core 4.3.10.RELEASE 

Die neueste Version der Abhängigkeit finden Sie hier.

Wir können die deleteRecursively () -Methode in FileSystemUtils verwenden , um das Löschen durchzuführen:

boolean result = FileSystemUtils.deleteRecursively(file);

Die jüngsten Versionen von Java bieten neuere Möglichkeiten zum Ausführen solcher E / A-Vorgänge, die in den folgenden Abschnitten beschrieben werden.

5. Verwenden von NIO2 mit Java 7

Java 7 führte eine völlig neue Methode zur Ausführung von Dateivorgängen mithilfe von Dateien ein . Es ermöglicht uns, einen Verzeichnisbaum zu durchlaufen und Rückrufe für auszuführende Aktionen zu verwenden.

public void whenDeletedWithNIO2WalkFileTree_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); Files.walkFileTree(pathToBeDeleted, new SimpleFileVisitor() { @Override public FileVisitResult postVisitDirectory( Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile( Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } }); assertFalse("Directory still exists", Files.exists(pathToBeDeleted)); }

Die Files.walkFileTree () -Methode durchläuft einen Dateibaum und gibt Ereignisse aus. Wir müssen Rückrufe für diese Ereignisse angeben. In diesem Fall definieren wir SimpleFileVisitor so , dass die folgenden Aktionen für die generierten Ereignisse ausgeführt werden:

  1. Eine Datei besuchen - löschen
  2. Besuchen Sie ein Verzeichnis, bevor Sie seine Einträge verarbeiten - tun Sie nichts
  3. Besuchen Sie ein Verzeichnis nach der Verarbeitung seiner Einträge - löschen Sie das Verzeichnis, da alle Einträge in diesem Verzeichnis inzwischen verarbeitet (oder gelöscht) worden wären
  4. Es kann keine Datei aufgerufen werden - IOException erneut auslösen , die den Fehler verursacht hat

Weitere Informationen zu NIO2-APIs zur Behandlung von Dateivorgängen finden Sie in der Einführung in die Java NIO2-Datei-API.

6. Verwenden von NIO2 mit Java 8

Seit Java 8 bietet die Stream-API eine noch bessere Möglichkeit, ein Verzeichnis zu löschen:

@Test public void whenDeletedWithFilesWalk_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); Files.walk(pathToBeDeleted) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); assertFalse("Directory still exists", Files.exists(pathToBeDeleted)); }

Hier Files.walk () liefert einen Strom von dem Weg , dass wir Art in umgekehrter Reihenfolge. Dadurch werden die Pfade, die den Inhalt von Verzeichnissen angeben, vor den Verzeichnissen selbst platziert. Danach ordnet es den Pfad zur Datei zu und löscht jede Datei.

7. Fazit

In diesem kurzen Tutorial haben wir verschiedene Möglichkeiten zum Löschen eines Verzeichnisses untersucht. Während wir sahen, wie Rekursion zum Löschen verwendet wird, haben wir uns auch einige Bibliotheken, NIO2-Hebelereignisse und Java 8 Path Stream unter Verwendung eines funktionalen Programmierparadigmas angesehen.

Alle Quellcodes und Testfälle für diesen Artikel sind auf GitHub verfügbar.