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:
- Få alt innholdet i katalogen som skal slettes
- Slett alle barn som ikke er en katalog (gå ut av rekursjon)
- For hver underkatalog til gjeldende katalog, start med trinn 1 (rekursivt trinn)
- 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:
- Å besøke en fil - slett den
- Å besøke en katalog før du behandler oppføringene - gjør ingenting
- Besøk en katalog etter å ha behandlet oppføringene - slett katalogen, da alle oppføringene i denne katalogen ville blitt behandlet (eller slettet) nå
- 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.