Odstráňte adresár rekurzívne v prostredí Java

1. Úvod

V tomto článku si ukážeme, ako rekurzívne odstrániť adresár v obyčajnej Jave. Pozrime sa tiež na niektoré alternatívy odstránenia adresárov pomocou externých knižníc.

2. Rekurzívne odstránenie adresára

Java má možnosť vymazať adresár. To si však vyžaduje, aby bol adresár prázdny. Potrebujeme teda použiť rekurziu na odstránenie konkrétneho neprázdneho adresára:

  1. Získajte všetok obsah adresára, ktorý chcete odstrániť
  2. Odstrániť všetky deti, ktoré nie sú adresárom (ukončiť rekurziu)
  3. Pre každý podadresár aktuálneho adresára začnite krokom 1 (rekurzívny krok)
  4. Odstráňte adresár

Implementujme tento jednoduchý algoritmus:

boolean deleteDirectory (File directoryToBeDeleted) {File [] allContents = directoryToBeDeleted.listFiles (); if (allContents! = null) {for (File file: allContents) {deleteDirectory (file); }} vratit adresarToBeDeleted.delete (); }

Túto metódu je možné testovať pomocou priameho testovacieho prípadu:

@Test public void givenDirectory_whenDeletedWithRecursion_thenIsGone () vyvolá IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); boolean result = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (výsledok); assertFalse ("Adresár stále existuje", Files.exists (pathToBeDeleted)); }

The @ Predtým metóda našej testovacej triedy vytvorí adresárový strom s podadresármi a súbormi na pathToBeDeleted umiestnenie a @ Potom metóda v prípade potreby vyčistí adresár.

Ďalej sa pozrime, ako môžeme dosiahnuť odstránenie pomocou dvoch najbežnejšie používaných knižníc - Apache commons-io a jarné rámce pružinové jadro. Obe tieto knižnice nám umožňujú mazať adresáre iba pomocou jedného riadku kódu.

3. Používanie FileUtils od commons-io

Najprv musíme pridať commons-io závislosť od projektu Maven:

 commons-io commons-io 2.5 

Najnovšiu verziu závislosti nájdete tu.

Teraz môžeme použiť FileUtils vykonávať akékoľvek operácie založené na súbore vrátane deleteDirectory () iba s jedným vyhlásením:

FileUtils.deleteDirectory (súbor);

4. Používanie FileSystemUtils od jari

Prípadne môžeme pridať spring-core závislosť od projektu Maven:

 org.springframework pružinové jadro 4.3.10.RELEASE 

Najnovšiu verziu závislosti nájdete tu.

Môžeme použiť deleteRecursively () metóda v FileSystemUtils vykonať odstránenie:

boolean result = FileSystemUtils.deleteRecursively (súbor);

Nedávne vydania Java ponúkajú novšie spôsoby vykonávania týchto operácií IO, ktoré sú popísané v nasledujúcich častiach.

5. Používanie NIO2 s Java 7

Java 7 predstavila úplne nový spôsob vykonávania operácií so súbormi pomocou Súbory. Umožňuje nám prechádzať stromom adresárov a používať spätné volania na vykonávanie akcií.

public void whenDeletedWithNIO2WalkFileTree_thenIsGone () vyvolá IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, new SimpleFileVisitor () {@Override public FileVisitResult postVisitDirectory (cesta dir, IOException exc) hodí IOException {Files.delete (dir); návrat FileVisitResult.CONTINUE;} @Override verejný súbor FileVisitResult ) hodí IOException {Files.delete (file); return FileVisitResult.CONTINUE;}}); assertFalse ("Adresár stále existuje", Files.exists (pathToBeDeleted)); }

The Files.walkFileTree () metóda prechádza stromom súborov a vysiela udalosti. Pre tieto udalosti musíme určiť spätné volania. Takže v tomto prípade budeme definovať SimpleFileVisitor vykonať pre generované udalosti nasledujúce akcie:

  1. Návšteva súboru - odstráňte ho
  2. Návšteva adresára pred spracovaním jeho položiek - nerobte nič
  3. Návšteva adresára po spracovaní jeho položiek - odstráňte adresár, pretože všetky záznamy v tomto adresári by už boli spracované (alebo odstránené).
  4. Nepodarilo sa navštíviť súbor - opätovné vyvolanie Výnimka IO ktoré spôsobilo zlyhanie

Viac podrobností o rozhraniach API NIO2 týkajúcich sa manipulácie so súbormi nájdete v časti Úvod do Java NIO2 File API.

6. Používanie NIO2 s Java 8

Od verzie Java 8 ponúka Stream API ešte lepší spôsob odstránenia adresára:

@Test public void whenDeletedWithFilesWalk_thenIsGone () vyvolá IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted) .sorted (Comparator.reverseOrder ()) .map (Path :: toFile) .forEach (File :: delete); assertFalse ("Adresár stále existuje", Files.exists (pathToBeDeleted)); }

Tu, Files.walk () vracia a Prúd z Cesta že triedime v opačnom poradí. Toto umiestni cesty označujúce obsah adresárov pred samotné adresáre. Potom sa to mapuje Cesta do Súbor a vymaže každú z nich Súbor.

7. Záver

V tomto rýchlom návode sme preskúmali rôzne spôsoby odstránenia adresára. Keď sme videli, ako na odstránenie použiť rekurziu, pozreli sme sa tiež na niektoré knižnice, NIO2 využívajúce udalosti a Java 8 Path Stream využívajúce paradigmu funkčného programovania.

Všetky zdrojové kódy a testovacie prípady pre tento článok sú k dispozícii na GitHub.


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