Padam Direktori secara berulang di Java

1. Pengenalan

Dalam artikel ini, kami akan menerangkan cara menghapus direktori secara berulang di Java biasa. Kami juga akan melihat beberapa alternatif untuk menghapus direktori menggunakan perpustakaan luaran.

2. Memadamkan Direktori secara berulang

Java mempunyai pilihan untuk menghapus direktori. Walau bagaimanapun, ini memerlukan direktori kosong. Oleh itu, kita perlu menggunakan rekursi untuk menghapus direktori yang tidak kosong:

  1. Dapatkan semua kandungan direktori untuk dihapuskan
  2. Padamkan semua anak yang bukan direktori (keluar dari rekursi)
  3. Untuk setiap subdirektori direktori semasa, mulakan dengan langkah 1 (langkah rekursif)
  4. Padamkan direktori

Mari kita laksanakan algoritma mudah ini:

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

Kaedah ini boleh diuji dengan menggunakan kes ujian langsung:

@Test public void givenDirectory_whenDeletedWithRecursion_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); boolean result = deleteDirectory(pathToBeDeleted.toFile()); assertTrue(result); assertFalse( "Directory still exists", Files.exists(pathToBeDeleted)); }

The @Before kaedah kelas ujian kami mencipta pokok direktori dengan subdirektori dan fail di pathToBeDeleted lokasi dan @After Cara membersihkan direktori jika diperlukan.

Seterusnya, mari kita lihat bagaimana kita dapat mencapai penghapusan menggunakan dua perpustakaan yang paling biasa digunakan - Apache's commons-io dan Spring Framework's spring-core. Kedua-dua perpustakaan ini membolehkan kami menghapus direktori dengan hanya menggunakan satu baris kod.

3. Menggunakan FileUtils dari commons-io

Pertama, kita perlu menambahkan kebergantungan commons-io ke projek Maven:

 commons-io commons-io 2.5 

Versi ketergantungan terkini boleh didapati di sini.

Sekarang, kita dapat menggunakan FileUtils untuk melakukan operasi berdasarkan fail termasuk deleteDirectory () dengan hanya satu pernyataan:

FileUtils.deleteDirectory(file);

4. Menggunakan FileSystemUtils dari Spring

Sebagai alternatif, kita dapat menambahkan kebergantungan pring-core ke projek Maven:

 org.springframework spring-core 4.3.10.RELEASE 

Versi ketergantungan terkini boleh didapati di sini.

Kita boleh menggunakan kaedah deleteRecursively () dalam FileSystemUtils untuk melakukan penghapusan:

boolean result = FileSystemUtils.deleteRecursively(file);

Pelepasan Java baru-baru ini menawarkan cara baru untuk melakukan operasi IO seperti yang dijelaskan dalam bahagian berikut.

5. Menggunakan NIO2 Dengan Java 7

Java 7 memperkenalkan cara baru untuk menjalankan operasi fail menggunakan Files . Ini memungkinkan kita melintasi pohon direktori dan menggunakan panggilan balik untuk tindakan yang akan dilakukan.

public void whenDeletedWithNIO2WalkFileTree_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); Files.walkFileTree(pathToBeDeleted, new SimpleFileVisitor() { @Override public FileVisitResult postVisitDirectory( Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile( Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } }); assertFalse("Directory still exists", Files.exists(pathToBeDeleted)); }

Kaedah Files.walkFileTree () melintasi pokok fail dan mengeluarkan peristiwa. Kita perlu menentukan panggilan balik untuk acara ini. Jadi, dalam kes ini, kami akan menentukan SimpleFileVisitor untuk mengambil tindakan berikut untuk peristiwa yang dihasilkan:

  1. Melawat fail - padamkannya
  2. Melawat direktori sebelum memproses entri - jangan buat apa-apa
  3. Mengunjungi direktori setelah memproses entri-hapus direktori, kerana semua entri dalam direktori ini sudah diproses (atau dihapus) sekarang
  4. Tidak dapat melawat fail - jalankan semula IOException yang menyebabkan kegagalan

Sila rujuk Pengenalan API File NIO2 Java untuk keterangan lebih lanjut mengenai API NIO2 mengenai pengendalian operasi fail.

6. Menggunakan NIO2 Dengan Java 8

Sejak Java 8, Stream API menawarkan cara yang lebih baik untuk menghapus direktori:

@Test public void whenDeletedWithFilesWalk_thenIsGone() throws IOException { Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME); Files.walk(pathToBeDeleted) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); assertFalse("Directory still exists", Files.exists(pathToBeDeleted)); }

Di sini, Files.walk () mengembalikan Stream daripada jalan yang kita semacam secara terbalik. Ini meletakkan jalan yang menunjukkan isi direktori sebelum direktori itu sendiri. Selepas itu memetakan Path to File dan menghapus setiap File.

7. Kesimpulannya

Dalam tutorial ringkas ini, kami meneroka pelbagai cara menghapus direktori. Walaupun kami melihat bagaimana menggunakan rekursi untuk menghapus, kami juga melihat beberapa perpustakaan, acara memanfaatkan NIO2 dan Java 8 Path Stream yang menggunakan paradigma pengaturcaraan yang berfungsi.

Semua kod sumber dan kes ujian untuk artikel ini terdapat di GitHub.