Verwijder een directory recursief in Java

1. Inleiding

In dit artikel laten we zien hoe u een map recursief verwijdert in gewoon Java. We zullen ook enkele alternatieven bekijken voor het verwijderen van mappen met behulp van externe bibliotheken.

2. Een directory recursief verwijderen

Java heeft een optie om een ​​directory te verwijderen. Dit vereist echter dat de directory leeg is. We moeten dus recursie gebruiken om een ​​bepaalde niet-lege map te verwijderen:

  1. Haal alle inhoud van de directory op die moet worden verwijderd
  2. Verwijder alle kinderen die geen map zijn (verlaat de recursie)
  3. Begin voor elke submap van de huidige map met stap 1 (recursieve stap)
  4. Verwijder de directory

Laten we dit eenvoudige algoritme implementeren:

boolean deleteDirectory (BestandsdirectoryToBeDeleted) {Bestand [] allContents = directoryToBeDeleted.listFiles (); if (allContents! = null) {voor (Bestandsbestand: allContents) {deleteDirectory (bestand); }} return directoryToBeDeleted.delete (); }

Deze methode kan worden getest met behulp van een eenvoudige testcase:

@Test openbare leegte gegevenDirectory_whenDeletedWithRecursion_thenIsGone () gooit IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); booleaans resultaat = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (resultaat); assertFalse ("Directory bestaat nog steeds", Files.exists (pathToBeDeleted)); }

De @Voordat methode van onze testklasse maakt een mappenboom met submappen en bestanden op pathToBeDeleted locatie en @Na methode ruimt de directory op indien nodig.

Laten we vervolgens eens kijken hoe we verwijdering kunnen bereiken met behulp van twee van de meest gebruikte bibliotheken - Apache's commons-io en Spring Framework's lente-kern. Met beide bibliotheken kunnen we de mappen verwijderen met slechts een enkele regel code.

3. Met behulp van FileUtils van commons-io

Eerst moeten we de commons-io afhankelijkheid van het Maven-project:

 commons-io commons-io 2.5 

De laatste versie van de afhankelijkheid is hier te vinden.

Nu kunnen we gebruiken FileUtils om bestandsgebaseerde bewerkingen uit te voeren, inclusief deleteDirectory () met slechts één verklaring:

FileUtils.deleteDirectory (bestand);

4. Met behulp van FileSystemUtils vanaf het voorjaar

Als alternatief kunnen we de s toevoegenpring-core afhankelijkheid van het Maven-project:

 org.springframework spring-core 4.3.10.RELEASE 

De laatste versie van de afhankelijkheid is hier te vinden.

We kunnen de deleteRecursively () methode in FileSystemUtils om de verwijdering uit te voeren:

boolean result = FileSystemUtils.deleteRecursively (bestand);

De recente releases van Java bieden nieuwere manieren om dergelijke IO-bewerkingen uit te voeren, die in de volgende secties worden beschreven.

5. NIO2 gebruiken met Java 7

Java 7 introduceerde een geheel nieuwe manier om bestandsbewerkingen uit te voeren met behulp van Bestanden. Het stelt ons in staat om een ​​directorystructuur te doorlopen en callbacks te gebruiken voor uit te voeren acties.

public void whenDeletedWithNIO2WalkFileTree_thenIsGone () gooit IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, nieuwe SimpleFileVisitor () {@Override public FileVisitResult postVisitDirectory (Path dir, IOException exc) gooit IOException {Files.delete (dir); retourneer FileVisitResult.CONTINUE;} @Override PathAttes public FileVisitAttes ) gooit IOException {Files.delete (file); return FileVisitResult.CONTINUE;}}); assertFalse ("Directory bestaat nog steeds", Files.exists (pathToBeDeleted)); }

De Files.walkFileTree () methode doorloopt een bestandsboom en zendt gebeurtenissen uit. We moeten callbacks specificeren voor deze evenementen. Dus in dit geval zullen we definiëren SimpleFileVisitor om de volgende acties te ondernemen voor de gegenereerde gebeurtenissen:

  1. Een bestand bezoeken - verwijder het
  2. Een directory bezoeken voordat de items worden verwerkt - niets doen
  3. Een directory bezoeken na het verwerken van de vermeldingen - verwijder de directory, aangezien alle vermeldingen in deze directory inmiddels zouden zijn verwerkt (of verwijderd)
  4. Kan een bestand niet bezoeken - opnieuw gooien IOException dat de mislukking veroorzaakte

Raadpleeg Inleiding tot de Java NIO2-bestands-API voor meer informatie over NIO2-API's voor het afhandelen van bestandsbewerkingen.

6. Met behulp van NIO2 met Java 8

Sinds Java 8 biedt Stream API een nog betere manier om een ​​directory te verwijderen:

@Test openbare leegte whenDeletedWithFilesWalk_thenIsGone () gooit IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted) .sorted (Comparator.reverseOrder ()) .map (Path :: toFile) .forEach (File :: delete); assertFalse ("Directory bestaat nog steeds", Files.exists (pathToBeDeleted)); }

Hier, Files.walk () geeft een terug Stroom van Pad die we in omgekeerde volgorde sorteren. Dit plaatst de paden die de inhoud van mappen aangeven voor de mappen zelf. Daarna wordt het in kaart gebracht Pad naar het dossier en verwijdert elk Het dossier.

7. Conclusie

In deze korte tutorial hebben we verschillende manieren onderzocht om een ​​directory te verwijderen. Hoewel we zagen hoe we recursie konden gebruiken om te verwijderen, hebben we ook gekeken naar enkele bibliotheken, waarbij NIO2 gebruikmaakt van gebeurtenissen en Java 8 Path Stream gebruikmaakt van een functioneel programmeerparadigma.

Alle broncode en testcases voor dit artikel zijn beschikbaar op GitHub.