Rekurzivno brisanje direktorija na Javi

1. Uvod

U ovom ćemo članku ilustrirati kako rekurzivno brisati direktorij na običnoj Javi. Također ćemo razmotriti neke alternative za brisanje direktorija pomoću vanjskih knjižnica.

2. Rekurzivno brisanje direktorija

Java ima mogućnost brisanja direktorija. Međutim, to zahtijeva da direktorij bude prazan. Dakle, trebamo koristiti rekurziju za brisanje određenog direktorija koji nije prazan:

  1. Neka se sav sadržaj direktorija izbriše
  2. Izbrišite sve podređene dijelove koji nisu direktorij (izlaz iz rekurzije)
  3. Za svaki poddirektorij trenutnog direktorija započnite s korakom 1 (rekurzivni korak)
  4. Izbrišite direktorij

Primijenimo ovaj jednostavni algoritam:

logički deleteDirectory (Datoteka directoryToBeDeleted) {Datoteka [] allContents = directoryToBeDeleted.listFiles (); if (allContents! = null) {for (Datoteka datoteke: allContents) {deleteDirectory (datoteka); }} return directoryToBeDeleted.delete (); }

Ova se metoda može testirati pomoću jednostavnog test slučaja:

@Test javna praznina givenDirectory_whenDeletedWithRecursion_thenIsGone () baca IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); boolean rezultat = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (rezultat); assertFalse ("Direktorij i dalje postoji", Files.exists (pathToBeDeleted)); }

The @Prije metoda naše test klase stvara stablo direktorija s poddirektorijima i datotekama na pathToBeDeleted mjesto i @Nakon metoda čisti direktorij ako je potrebno.

Dalje, pogledajmo kako možemo postići brisanje pomoću dvije najčešće korištene knjižnice - Apacheove zajedničko-io i Spring Framework-a opružna jezgra. Obje ove knjižnice omogućuju nam brisanje direktorija pomoću samo jednog retka koda.

3. Korištenje FileUtils iz zajedničko-io

Prvo, moramo dodati zajedničko-io ovisnost o projektu Maven:

 commons-io commons-io 2.5 

Najnoviju verziju ovisnosti možete pronaći ovdje.

Sada možemo koristiti FileUtils za izvođenje bilo kakvih operacija na temelju datoteka, uključujući deleteDirectory () sa samo jednom izjavom:

FileUtils.deleteDirectory (datoteka);

4. Korištenje FileSystemUtils iz proljeća

Alternativno, možemo dodati spring-core ovisnost o projektu Maven:

 org.springframework opruga-jezgra 4.3.10.OSLOBOĐENJE 

Najnoviju verziju ovisnosti možete pronaći ovdje.

Možemo koristiti deleteRecursively () metoda u FileSystemUtils da biste izvršili brisanje:

boolean rezultat = FileSystemUtils.deleteRecursively (datoteka);

Nedavna izdanja Jave nude novije načine izvođenja takvih IO operacija opisanih u sljedećim odjeljcima.

5. Korištenje NIO2 s Javom 7

Java 7 predstavila je potpuno novi način izvođenja operacija datoteka Datoteke. Omogućuje nam prelazak stabla direktorija i korištenje povratnih poziva za radnje koje treba izvršiti.

javna praznina whenDeletedWithNIO2WalkFileTree_thenIsGone () baca IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, novi SimpleFileVisitor () {@Override public FileVisitResult postVisitDirectory (dir direktorija, IOException exc) baca IOException {Files.delete (dir); return FileVisitResult.CONTINUERatultVitverFitVisFitVisFitVisFitViverFitVisFitVisFitVisFitVisFitVisFitVisFitVisFitVisFitVisFitVisFitViverTeitResult; ) baca IOException {Files.delete (datoteka); return FileVisitResult.CONTINUE;}}); assertFalse ("Direktorij i dalje postoji", Files.exists (pathToBeDeleted)); }

The Files.walkFileTree () metoda prelazi stablo datoteka i emitira događaje. Moramo odrediti povratne pozive za ove događaje. Dakle, u ovom ćemo slučaju definirati SimpleFileVisitor poduzeti sljedeće radnje za generirane događaje:

  1. Posjećivanje datoteke - izbrišite je
  2. Posjetite direktorij prije obrade njegovih unosa - ne poduzmite ništa
  3. Posjet direktorija nakon obrade njegovih unosa - izbrišite direktorij, jer bi svi unosi u ovom direktoriju do sada bili obrađeni (ili izbrisani)
  4. Nije moguće posjetiti datoteku - ponovno izvrši IOException to je uzrokovalo neuspjeh

Pogledajte Uvod u Java NIO2 File API za više detalja o NIO2 API-ima o rukovanju datotekama.

6. Korištenje NIO2 s Javom 8

Od Java 8, Stream API nudi još bolji način brisanja direktorija:

@Test public void whenDeletedWithFilesWalk_thenIsGone () baca IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted). Sortirano (Comparator.reverseOrder ()) .map (Path :: toFile) .forEach (File :: delete); assertFalse ("Direktorij i dalje postoji", Files.exists (pathToBeDeleted)); }

Ovdje, Files.walk () vraća a Stream od Staza da sortiramo obrnutim redoslijedom. To postavlja putove koji označavaju sadržaj direktorija ispred samih direktorija. Nakon toga mapira Staza do Datoteka i briše svaku Datoteka.

7. Zaključak

U ovom smo brzom vodiču istražili različite načine brisanja direktorija. Iako smo vidjeli kako koristiti rekurziju za brisanje, pogledali smo i neke knjižnice, događaje iskorištavanja NIO2 i Java 8 Path Stream koji koristi funkcionalnu paradigmu programiranja.

Svi izvorni kod i testovi za ovaj članak dostupni su na GitHubu.