Daftar file dalam direktori
Anda dapat dengan mudah membuat daftar nama file dari semua file dalam direktori menggunakan metode list() dari kelas File. Jika Anda ingin mendapatkan file selain hanya nama file, Anda dapat menggunakan metode listFiles()-nya. Ini sangat sederhana, yang sulit adalah bagaimana memproses daftar yang dikembalikan. Daripada menggunakan iterator eksternal tradisional yang panjang, kami menggunakan ekspresi fungsional yang elegan untuk menelusuri daftar ini. Di sini kita juga harus menggunakan antarmuka CloseableStream JDK yang baru dan beberapa fungsi tingkat tinggi terkait.
Kode berikut mencantumkan nama semua file di direktori saat ini.
Copy kode kodenya sebagai berikut:
File.daftar(Jalur.dapatkan("."))
.forEach(Sistem.keluar::println);
Jika Anda ingin membuat daftar direktori lain, Anda dapat mengganti "." dengan path lengkap dari direktori yang ingin Anda akses.
Di sini, pertama-tama kita menggunakan metode get() dari Paths untuk membuat instance Path melalui sebuah string. Kemudian kita memperoleh objek ClosableStream melalui metode list() dari kelas alat Files, dan kita dapat menggunakannya untuk melintasi semua file dalam direktori. Kami kemudian menggunakan iterator internal forEach() untuk mencetak nama file. Pertama mari kita lihat beberapa hasil keluaran dari kode ini: daftar file dan subdirektori di direktori saat ini.
Copy kode kodenya sebagai berikut:
./aSampleFiles.txt
./bin
./fpij
...
Jika kita hanya ingin mendapatkan subdirektori dari direktori saat ini, bukan file, kita bisa menggunakan metode filter():
Copy kode kodenya sebagai berikut:
File.daftar(Jalur.dapatkan("."))
.filter(File::isDirectory)
.forEach(Sistem.keluar::println);
Metode ilter() memfilter direktori dari aliran file. Kita meneruskan referensi ke metode isDirectory dari kelas Files alih-alih meneruskan ekspresi lambda. Ingatlah bahwa metode filter() memerlukan tipe Predikat yang mengembalikan nilai boolean, dan metode ini tepat. Terakhir kami menggunakan iterator internal untuk mencetak nama direktori. Program ini akan mencetak subdirektori dari direktori saat ini.
Copy kode kodenya sebagai berikut:
./bin
./fpij
./keluaran
...
Menulis dengan cara ini jauh lebih sederhana dan menghemat banyak kode dibandingkan dengan cara menulis yang lama di Java. Mari kita lihat cara membuat daftar file yang cocok dengan pola tertentu.
Daftar file yang ditentukan dalam direktori
Java telah lama menyediakan varian metode list() untuk memfilter nama file. Versi metode list() ini menerima parameter bertipe FilenameFilter. Antarmuka ini hanya memiliki satu metode terima (), yang menerima dua parameter: Dir file (mewakili direktori), dan Nama string (mewakili nama file). Jika metode terima() mengembalikan nilai true, nama file akan muncul dalam daftar yang dikembalikan, jika tidak maka tidak akan muncul. Mari terapkan metode ini.
Pendekatan yang biasa dilakukan adalah meneruskan instance kelas dalam anonim yang mengimplementasikan antarmuka FilenameFilter ke metode list(). Sebagai contoh, mari kita lihat cara menggunakan metode ini untuk mengembalikan file .java di direktori fpij.
Copy kode kodenya sebagai berikut:
String terakhir[] file =
File baru("fpij").daftar(java.io.NamaFileFilter() baru {
boolean publik menerima(Direksi File akhir, nama String akhir) {
return name.endsWith(".java");
}
});
Sistem.keluar.println(file);
Ini sangat membutuhkan waktu dan usaha untuk menulis beberapa baris kode. Kode semacam ini terlalu berisik: membuat objek, memanggil fungsi, mendefinisikan kelas dalam anonim, menyematkan metode di kelas, dll. Kita tidak lagi harus menanggung rasa sakit ini, cukup berikan ekspresi lambda yang menerima dua parameter dan mengembalikan bollean. Kompiler Java akan mengurus sisanya.
Contoh sebelumnya dapat dengan mudah mengganti internal anonim dengan ekspresi lambda, namun masih ada ruang untuk pengoptimalan lebih lanjut. Alat DirectoryStream baru dapat membantu kita melintasi struktur direktori besar dengan lebih efisien. Mari kita coba metode ini. Ini adalah varian dari metode newDirectoryStream() yang menerima filter tambahan.
Copy kode kodenya sebagai berikut:
File.newDirectoryStream(
Jalur.mendapatkan("fpij"), jalur -> jalur.toString().endsWith(".java"))
.forEach(Sistem.keluar::println);
Dengan cara ini kita menyingkirkan kelas dalam anonim dan membuat kode rumit menjadi ringkas dan jelas. Output kedua versinya sama. Mari cetak file yang ditentukan.
Kode ini hanya akan menampilkan file .java di direktori yang ditentukan. Berikut adalah bagian dari outputnya:
Copy kode kodenya sebagai berikut:
fpij/Bandingkan.java
fpij/IterateString.java
fpij/ListDirs.java
...
Kami memfilter file berdasarkan nama file. Itu juga dapat dengan mudah difilter berdasarkan atribut file, seperti apakah file tersebut dapat dieksekusi, dapat dibaca, dapat ditulis, dll. Untuk melakukan ini, Anda memerlukan metode listFiles(), yang menerima parameter tipe FileFilter. Kami masih menggunakan ekspresi lambda alih-alih membuat kelas dalam anonim. Sekarang mari kita lihat contoh daftar semua file tersembunyi di direktori saat ini.
Copy kode kodenya sebagai berikut:
File terakhir[] file = File baru(".").listFiles(file -> file.isHidden());
Jika kita mengoperasikan direktori besar, kita dapat menggunakan DirectoryStream daripada memanggil metode pada File secara langsung.
Tanda tangan ekspresi lambda yang kita teruskan ke metode listFiles() sama dengan tanda tangan metode terima() antarmuka FileFilter. Ekspresi lambda ini menerima parameter dari instance File. Dalam contoh ini, nama parameternya adalah file. Jika file memiliki atribut tersembunyi, ia mengembalikan nilai benar, jika tidak, ia mengembalikan salah.
Faktanya, kode tersebut dapat disederhanakan lebih lanjut di sini. Kami tidak meneruskan ekspresi lambda. Melewati referensi metode akan membuat kode terlihat lebih ringkas:
Copy kode kodenya sebagai berikut:
File baru(".").listFiles(File::isHidden);
Kami pertama kali mengimplementasikannya menggunakan ekspresi lambda, lalu memfaktorkannya ulang agar lebih ringkas menggunakan referensi metode. Jika kita menulis kode baru, tentunya kita harus menggunakan cara ringkas ini. Jika penerapan yang rapi seperti itu dapat ditemukan sejak dini, kami tentu akan memprioritaskan penggunaannya. Ada pepatah yang mengatakan "buatlah berfungsi dulu, baru jadikan lebih baik". Biarkan kode berjalan terlebih dahulu. Setelah kami memperjelasnya, kami akan mempertimbangkan kesederhanaan dan kinerja untuk pengoptimalan.
Kami menggunakan contoh untuk memfilter file tertentu dari direktori. Mari kita lihat cara melintasi subdirektori di bawah direktori tertentu.