Apakah ada cara untuk menghapus seluruh direktori secara rekursif di Jawa?
Dalam kasus normal, dimungkinkan untuk menghapus direktori kosong. Namun ketika datang untuk menghapus seluruh direktori dengan konten, tidak sesederhana itu lagi.
Bagaimana Anda menghapus seluruh direktori dengan konten di Jawa?
java
file-io
filesystems
delete-directory
paweloque
sumber
sumber
Jawaban:
Anda harus memeriksa commons-io Apache . Ini memiliki kelas FileUtils yang akan melakukan apa yang Anda inginkan.
sumber
Dengan Java 7, kita akhirnya bisa melakukan ini dengan deteksi symlink yang andal. (Saya tidak menganggap Apache commons-io memiliki deteksi symlink yang andal saat ini, karena tidak menangani tautan pada Windows yang dibuat dengan
mklink
.)Demi sejarah, inilah jawaban pra-Java 7, yang mengikuti symlink.
sumber
foo
dengan tautanfoo/link
sedemikian rupalink->/
, panggilandelete(new File(foo))
akan menghapus sebanyak mungkin sistem file Anda seperti yang diizinkan oleh pengguna !!Di Java 7+ Anda bisa menggunakan
Files
kelas. Kode sangat sederhana:sumber
super.postVisitDirectory(dir, exc);
AndapostVisitDirectory
, untuk meledakkan jika jalan tidak bisa daftar direktori.One-liner solution (Java8) untuk menghapus semua file dan direktori secara rekursif termasuk direktori awal:
Kami menggunakan pembanding untuk pesanan terbalik, jika File :: delete tidak akan dapat menghapus direktori yang mungkin tidak kosong. Jadi, jika Anda ingin menyimpan direktori dan hanya menghapus file, cukup hapus komparatornya diurutkan () atau hapus pengurutan sepenuhnya dan tambahkan filter file:
sumber
.sorted(Comparator.reverseOrder())
SaranComparator::reverseOrder
yang tidak bekerja. Lihat: stackoverflow.com/questions/43036611/….sorted((f1, f2) -> f2.compareTo(f1))
:, bandingkanf2
denganf1
alih - alihf1
denganf2
.Java 7 menambahkan dukungan untuk direktori berjalan dengan penanganan symlink:
Saya menggunakan ini sebagai fallback dari metode khusus platform (dalam kode yang belum diuji ):
(SystemUtils dari Apache Commons Lang . Proses bersifat pribadi tetapi perilakunya harus jelas.)
sumber
Hanya melihat solusi saya kurang lebih sama dengan erickson, hanya dikemas sebagai metode statis. Jatuhkan ini di suatu tempat, ini jauh lebih ringan daripada menginstal semua Apache Commons untuk sesuatu yang (seperti yang Anda lihat) cukup sederhana.
sumber
Solusi dengan tumpukan dan tanpa metode rekursif:
sumber
list*
metode untuk kelasjava.io.File
. Dari Javadocs: "Mengembalikan nol jika pathname abstrak ini tidak menunjukkan direktori, atau jika kesalahan I / O terjadi." Jadi:if (currList.length > 0) {
menjadiif (null != currList && currList.length > 0) {
Jika Anda memiliki Spring, Anda dapat menggunakan FileSystemUtils.deleteRecursively :
sumber
Jambu telah
Files.deleteRecursively(File)
mendukung sampai Jambu 9 .Dari Jambu 10 :
Oleh karena itu, tidak ada metode seperti itu di Jambu Biji 11 .
sumber
Atau jika Anda ingin menangani
IOException
:sumber
Files.walk(path).iterator().toSeq.reverse.foreach(Files.delete)
walk
Metode sudah menjamin traversal depth-first.Collections.reverseOrder()
sehingga kode Anda akanfor (Path p : Files.walk(directoryToDelete).sorted(reverseOrder()).toArray(Path[]::new))
menganggap itu telah diimpor secara statis.Comparator.reverseOrder
?Files.walk(dir) .sorted(Comparator.reverseOrder()) .toArray(Path[]::new))
sumber
sumber
f.delete()
bawahdeleteDirectory(f)
akan melempar NoSuchFileException karenadeleteDirectory(f)
sudah menghapus file itu. Setiap direktori akan menjadi jalur ketika dilewatkandeleteDirectory(f)
dan dihapus olehpath.delete()
. Karena itu, kita tidak perluf.delete()
diif f.isDerectory
bagian. Jadi, hapus saja dif.delete();
bawah deleteDirectory (f) dan itu akan berfungsi.Dua cara untuk gagal dengan symlink dan kode di atas ... dan tidak tahu solusinya.
Cara # 1
Jalankan ini untuk membuat tes:
Di sini Anda melihat file pengujian dan direktori pengujian Anda:
Kemudian jalankan deleteDirectory () commons-io Anda. Itu crash mengatakan file tidak ditemukan. Tidak yakin apa yang dilakukan contoh lain di sini. Perintah Linux rm hanya akan menghapus tautan, dan rm -r pada direktori juga akan.
Cara # 2
Jalankan ini untuk membuat tes:
Di sini Anda melihat file pengujian dan direktori pengujian Anda:
Kemudian jalankan commons-io deleteDirectory () atau kode contoh yang diposkan orang. Itu menghapus tidak hanya direktori, tetapi testfile Anda yang berada di luar direktori sedang dihapus. (Ini menyangkal direktori secara implisit, dan menghapus konten). rm -r hanya akan menghapus tautan. Anda perlu menggunakan sesuatu seperti ini untuk menghapus file-file yang direferensikan: "find -L dirtodelete -type f -exec rm {} \;".
sumber
Anda bisa menggunakan:
org.apache.commons.io.FileUtils.deleteQuietly(destFile);
Menghapus file, tidak pernah melempar pengecualian. Jika file adalah direktori, hapus dan semua sub-direktori. Perbedaan antara File.delete () dan metode ini adalah: Direktori yang akan dihapus tidak harus kosong. Tidak ada pengecualian yang dilemparkan ketika file atau direktori tidak dapat dihapus.
sumber
Solusi optimal yang menangani pengecualian secara konsisten dengan pendekatan yang dilemparkan oleh pengecualian dari suatu metode harus selalu menggambarkan apa yang coba dilakukan oleh metode tersebut (dan gagal):
sumber
Dalam proyek lawas, saya perlu membuat kode Java asli. Saya membuat kode ini mirip dengan kode Paulitex. Lihat itu:
Dan unit test:
sumber
Kode di bawah ini secara rekursif menghapus semua konten dalam folder yang diberikan.
sumber
Berikut ini adalah metode utama tulang kosong yang menerima argumen baris perintah, Anda mungkin perlu menambahkan kesalahan Anda sendiri memeriksa atau membentuknya sesuai keinginan Anda.
Saya harap itu membantu!
sumber
Mungkin solusi untuk masalah ini mungkin menerapkan kembali metode penghapusan kelas File menggunakan kode dari jawaban erickson:
sumber
Tanpa Commons IO dan <Java SE 7
sumber
Sementara file dapat dengan mudah dihapus menggunakan file.delete (), direktori diharuskan kosong untuk dihapus. Gunakan rekursi untuk melakukan ini dengan mudah. Sebagai contoh:
sumber
saya mengkodekan rutin ini yang memiliki 3 kriteria keselamatan untuk penggunaan yang lebih aman.
sumber
Nah, mari kita ambil contoh,
Untuk informasi lebih lanjut, lihat sumber daya di bawah ini
Hapus direktori
sumber
rm -rf
itu jauh lebih performant dariFileUtils.deleteDirectory
.Setelah melakukan tolok ukur yang luas, kami menemukan bahwa menggunakan
rm -rf
beberapa kali lebih cepat daripada menggunakanFileUtils.deleteDirectory
.Tentu saja, jika Anda memiliki direktori kecil atau sederhana, itu tidak masalah, tetapi dalam kasus kami, kami memiliki beberapa gigabyte dan sub direktori yang sangat bersarang di mana itu akan memakan waktu lebih dari 10 menit
FileUtils.deleteDirectory
dan hanya 1 menitrm -rf
.Inilah implementasi Java kami yang kasar untuk melakukan itu:
Pantas untuk dicoba jika Anda berurusan dengan direktori besar atau kompleks.
sumber
Jambu menyediakan satu-kapal:
MoreFiles.deleteRecursively()
.Tidak seperti banyak contoh yang dibagikan, ini merupakan tautan simbolik dan tidak akan (secara default) menghapus file di luar jalur yang disediakan.
sumber