Slett en katalog rekursivt i Java

1. Introduksjon

I denne artikkelen vil vi illustrere hvordan du sletter en katalog rekursivt i vanlig Java. Vi vil også se på noen alternativer for å slette kataloger ved hjelp av eksterne biblioteker.

2. Slette en katalog rekursivt

Java har et alternativ for å slette en katalog. Dette krever imidlertid at katalogen er tom. Så vi må bruke rekursjon for å slette en bestemt ikke-tom katalog:

  1. Få alt innholdet i katalogen som skal slettes
  2. Slett alle barn som ikke er en katalog (gå ut av rekursjon)
  3. For hver underkatalog til gjeldende katalog, start med trinn 1 (rekursivt trinn)
  4. Slett katalogen

La oss implementere denne enkle algoritmen:

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

Denne metoden kan testes ved hjelp av en enkel testtilfelle:

@Test offentlig ugyldig givenDirectory_whenDeletedWithRecursion_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); boolsk resultat = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (resultat); assertFalse ("Katalogen eksisterer fortsatt", Files.exists (pathToBeDeleted)); }

De @Før metoden i testklassen vår oppretter et katalogtrær med underkataloger og filer på pathToBeDeleted plassering og @Etter metoden rydder opp katalogen om nødvendig.

Deretter la oss se på hvordan vi kan oppnå sletting ved hjelp av to av de mest brukte bibliotekene - Apache's commons-io og Spring Framework's vårkjernen. Begge disse bibliotekene tillater oss å slette katalogene ved å bruke bare en enkelt linje med kode.

3. Bruke FileUtils fra commons-io

Først må vi legge til commons-io avhengighet av Maven-prosjektet:

 commons-io commons-io 2.5 

Den siste versjonen av avhengigheten finner du her.

Nå kan vi bruke FileUtils å utføre eventuelle filbaserte operasjoner inkludert deleteDirectory () med bare ett utsagn:

FileUtils.deleteDirectory (fil);

4. Bruke FileSystemUtils fra våren

Alternativt kan vi legge til spring-core avhengighet av Maven-prosjektet:

 org.springframework spring-core 4.3.10.RELEASE 

Den siste versjonen av avhengigheten finner du her.

Vi kan bruke deleteRecursively () metode i FileSystemUtils for å utføre slettingen:

boolsk resultat = FileSystemUtils.deleteRecursively (fil);

De nylige utgivelsene av Java tilbyr nyere måter å utføre slike IO-operasjoner beskrevet i de følgende avsnittene.

5. Bruke NIO2 med Java 7

Java 7 introduserte en helt ny måte å utføre filoperasjoner på Filer. Det lar oss krysse et katalogtreet og bruke tilbakeringinger for handlinger som skal utføres.

offentlig ugyldig nårDeletedWithNIO2WalkFileTree_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, ny SimpleFileVisitor () {@Override public FileVisitResult postVisitDirectory (Path dir, IOException exc) kaster IOException {Files.delete (dir); returner FileVisitResult.CONTINUE;} @Override resultat FileVitile FileVit ) kaster IOException {Files.delete (file); return FileVisitResult.CONTINUE;}}); assertFalse ("Katalogen eksisterer fortsatt", Files.exists (pathToBeDeleted)); }

De Files.walkFileTree () metode krysser et filtre og sender ut hendelser. Vi må spesifisere tilbakeringinger for disse hendelsene. Så, i dette tilfellet vil vi definere SimpleFileVisitor for å utføre følgende handlinger for de genererte hendelsene:

  1. Å besøke en fil - slett den
  2. Å besøke en katalog før du behandler oppføringene - gjør ingenting
  3. Besøk en katalog etter å ha behandlet oppføringene - slett katalogen, da alle oppføringene i denne katalogen ville blitt behandlet (eller slettet) nå
  4. Kunne ikke besøke en fil - kast tilbake IO Unntak som forårsaket feilen

Se Introduksjon til Java NIO2 File API for mer informasjon om NIO2 APIer for håndtering av filoperasjoner.

6. Bruke NIO2 Med Java 8

Siden Java 8 tilbyr Stream API en enda bedre måte å slette en katalog på:

@Test offentlig ugyldig nårDeletedWithFilesWalk_thenIsGone () kaster IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted) .sorted (Comparator.reverseOrder ()) .map (Path :: toFile) .forEach (File :: delete); assertFalse ("Katalogen eksisterer fortsatt", Files.exists (pathToBeDeleted)); }

Her, Files.walk () returnerer a Strøm av Sti som vi sorterer i omvendt rekkefølge. Dette plasserer stiene som angir innholdet i katalogene før selve katalogene. Deretter kartlegges det Sti til Fil og sletter hver Fil.

7. Konklusjon

I denne raske opplæringen utforsket vi forskjellige måter å slette en katalog på. Mens vi så hvordan vi kan bruke rekursjon til å slette, så vi også på noen biblioteker, NIO2 som utnytter hendelser og Java 8 Path Stream ved hjelp av et funksjonelt programmeringsparadigme.

Alle kildekoder og testtilfeller for denne artikkelen er tilgjengelig på GitHub.


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