Slet et bibliotek rekursivt i Java

1. Introduktion

I denne artikel illustrerer vi, hvordan du sletter en mappe rekursivt i almindelig Java. Vi ser også på nogle alternativer til at slette mapper ved hjælp af eksterne biblioteker.

2. Sletning af et bibliotek rekursivt

Java har en mulighed for at slette en mappe. Dette kræver dog, at biblioteket er tomt. Så vi skal bruge rekursion til at slette en bestemt ikke-tom mappe:

  1. Få alt indholdet af den mappe, der skal slettes
  2. Slet alle børn, der ikke er et bibliotek (afslutning fra rekursion)
  3. For hver underkatalog i det aktuelle bibliotek, start med trin 1 (rekursivt trin)
  4. Slet biblioteket

Lad os implementere denne enkle algoritme:

boolsk deleteDirectory (File directoryToBeDeleted) {File [] allContents = directoryToBeDeleted.listFiles (); hvis (allContents! = null) {for (File file: allContents) {deleteDirectory (file); }} returner directoryToBeDeleted.delete (); }

Denne metode kan testes ved hjælp af en ligetil test case:

@Test offentlig ugyldighed givenDirectory_whenDeletedWithRecursion_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); boolsk resultat = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (resultat); assertFalse ("Katalog findes stadig", Files.exists (pathToBeDeleted)); }

Det @Før metode i vores testklasse opretter et katalogtræ med underkataloger og filer på pathToBeDeleted placering og @Efter metode rydder op kataloget, hvis det kræves.

Lad os derefter se på, hvordan vi kan opnå sletning ved hjælp af to af de mest anvendte biblioteker - Apache's commons-io og Spring Framework's fjederkerne. Begge disse biblioteker giver os mulighed for at slette mapperne ved hjælp af kun en enkelt kodelinje.

3. Brug FileUtils fra commons-io

Først skal vi tilføje commons-io afhængighed af Maven-projektet:

 commons-io commons-io 2.5 

Den seneste version af afhængigheden kan findes her.

Nu kan vi bruge FileUtils til at udføre filbaserede operationer inklusive deleteDirectory () med kun en erklæring:

FileUtils.deleteDirectory (fil);

4. Brug FileSystemUtils fra foråret

Alternativt kan vi tilføje spring-core afhængighed af Maven-projektet:

 org.springframework spring-core 4.3.10.RELEASE 

Den seneste version af afhængigheden kan findes her.

Vi kan bruge deleteRecursively () metode i FileSystemUtils at udføre sletningen:

boolsk resultat = FileSystemUtils.deleteRecursively (fil);

De nylige udgivelser af Java tilbyder nyere måder til at udføre sådanne IO-operationer beskrevet i de følgende afsnit.

5. Brug af NIO2 med Java 7

Java 7 introducerede en helt ny måde at udføre filoperationer på Filer. Det giver os mulighed for at krydse et katalogtræ og bruge tilbagekald til handlinger, der skal udføres.

offentlig ugyldig nårDeletedWithNIO2WalkFileTree_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, ny SimpleFileVisitor () {@Override offentlig FileVisitResult postVisitDirectory (sti dir, IOException exc) kaster IOException {Files.delete (dir); returner FileVisitResult.CONTINUE;} @Override resultat FileFis fileVis ) kaster IOException {Files.delete (fil); returner FileVisitResult.CONTINUE;}}); assertFalse ("Katalog findes stadig", Files.exists (pathToBeDeleted)); }

Det Files.walkFileTree () metode krydser et filtræ og udsender begivenheder. Vi er nødt til at specificere tilbagekald til disse begivenheder. Så i dette tilfælde vil vi definere SimpleFileVisitor at tage følgende handlinger for de genererede begivenheder:

  1. Besøg en fil - slet den
  2. Besøg et bibliotek, før du behandler dets poster - gør ingenting
  3. Besøg et bibliotek efter behandling af dets poster - slet biblioteket, da alle poster i denne mappe nu ville være blevet behandlet (eller slettet)
  4. Kan ikke besøge en fil - retrow IOUndtagelse der forårsagede fejlen

Se Introduktion til Java NIO2 File API for at få flere oplysninger om NIO2 API'er til håndtering af filhandlinger.

6. Brug NIO2 med Java 8

Siden Java 8 tilbyder Stream API en endnu bedre måde at slette en mappe på:

@Test offentlig ugyldig nårDeletedWithFilesWalk_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted) .sorteret (Comparator.reverseOrder ()). Kort (Sti :: til fil). ForEach (Fil :: slet); assertFalse ("Katalog findes stadig", Files.exists (pathToBeDeleted)); }

Her, Files.walk () returnerer a Strøm af Sti at vi sorterer i omvendt rækkefølge. Dette placerer stier, der angiver indholdet af mapper, før selve mapper. Derefter kortlægges det Sti til Fil og sletter hver Fil.

7. Konklusion

I denne hurtige vejledning undersøgte vi forskellige måder at slette en mappe på. Mens vi så, hvordan man bruger rekursion til at slette, så vi også på nogle biblioteker, NIO2-udnyttelse af begivenheder og Java 8 Path Stream ved hjælp af et funktionelt programmeringsparadigme.

Alle kildekoder og testtilfælde til denne artikel er tilgængelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found