Saya benar-benar bingung sekarang - kebanyakan karena terminologi, saya kira. Bisakah seseorang menjelaskan kepada saya perbedaannya, atau berikan beberapa tautan ke materi anti-tiruan? Terutama URI ke URL dan Resource to File? Bagi saya, rasanya mereka harus sama, masing-masing ...
Terminologi ini membingungkan dan terkadang membingungkan, dan sebagian besar lahir dari evolusi Java sebagai API dan platform seiring waktu. Untuk memahami bagaimana istilah-istilah ini berarti apa yang mereka lakukan, penting untuk mengenali dua hal yang memengaruhi desain Java:
- Kompatibilitas mundur. Aplikasi lama harus berjalan pada instalasi yang lebih baru, idealnya tanpa modifikasi. Ini berarti bahwa API lama (dengan nama dan terminologinya) perlu dipertahankan melalui semua versi yang lebih baru.
- Lintas platform. API harus menyediakan abstraksi yang dapat digunakan dari platform yang mendasarinya, apakah itu sistem operasi atau browser.
Saya akan menjelaskan konsep dan bagaimana mereka muncul. Saya akan menjawab pertanyaan Anda yang lain, pertanyaan spesifik setelah itu, karena saya mungkin harus mengacu pada sesuatu di bagian pertama.
Apa itu "Sumber Daya"?
Sepotong data abstrak dan generik yang dapat ditemukan dan dibaca. Secara longgar dikatakan, Java menggunakan ini untuk merujuk ke "file" yang mungkin bukan file tetapi mewakili bagian data bernama. Itu tidak memiliki kelas langsung atau representasi antarmuka di Java , tetapi karena propertinya (dapat ditemukan, dapat dibaca) sering diwakili oleh URL.
Karena salah satu tujuan desain awal Java adalah untuk dijalankan di dalam browser, sebagai aplikasi kotak pasir (applet!) Dengan hak / hak istimewa / izin keamanan yang sangat terbatas, Java membuat perbedaan yang jelas (teoretis) antara file (sesuatu di lokal). sistem file) dan sumber daya (sesuatu yang perlu dibaca). Inilah sebabnya mengapa membaca sesuatu yang berhubungan dengan aplikasi (ikon, file kelas, dan sebagainya) dilakukan melalui ClassLoader.getResource
dan bukan melalui kelas File.
Sayangnya, karena "resource" juga merupakan istilah umum yang berguna di luar interpretasi ini, ia juga digunakan untuk menamai hal-hal yang sangat spesifik (misalnya class ResourceBundle , UIResource , Resource ) yang dalam pengertian ini bukan merupakan resource.
Kelas utama yang mewakili (jalur ke) sumber daya adalah java.nio.file.Path , java.io.File , java.net.URI , dan java.net.URL .
File (java.io, 1.0)
Representasi abstrak dari nama jalur file dan direktori.
Kelas File mewakili sumber daya yang dapat dijangkau melalui sistem file asli platform . Ini hanya berisi nama file, jadi ini lebih merupakan jalur (lihat nanti) yang ditafsirkan platform host sesuai dengan pengaturan, aturan, dan sintaksnya sendiri.
Perhatikan bahwa File tidak perlu menunjuk ke sesuatu yang lokal , hanya sesuatu yang dipahami oleh platform host dalam konteks akses file, misalnya jalur UNC di Windows. Jika Anda memasang file ZIP sebagai sistem file di OS Anda, maka File akan membaca entri yang ada di dalamnya dengan baik.
URL (java.net, 1.0)
URL Kelas mewakili Uniform Resource Locator, penunjuk ke "sumber daya" di World Wide Web. Sumber daya dapat berupa sesuatu yang sederhana seperti file atau direktori, atau dapat menjadi referensi ke objek yang lebih rumit, seperti kueri ke database atau ke mesin pencari.
Bersamaan dengan konsep sumber daya, URL merepresentasikan sumber daya tersebut dengan cara yang sama saat kelas File merepresentasikan file di platform host: sebagai string terstruktur yang mengarah ke sumber daya. URL juga berisi skema yang memberi petunjuk tentang cara menjangkau sumber daya (dengan "file:" menjadi "tanyakan platform host"), dan memungkinkan untuk menunjuk sumber daya melalui HTTP, FTP, di dalam JAR, dan yang lainnya.
Sayangnya, URL datang dengan sintaks dan terminologinya sendiri, termasuk penggunaan "file" dan "path". Jika URL adalah file-URL, URL.getFile akan mengembalikan string yang identik dengan string jalur dari file yang direferensikan.
Class.getResource
mengembalikan URL: lebih fleksibel daripada mengembalikan File, dan telah melayani kebutuhan sistem seperti yang dibayangkan di awal 1990-an.
URI (java.net, 1.4)
Merepresentasikan referensi Uniform Resource Identifier (URI).
URI adalah abstraksi (sedikit) atas URL. Perbedaan antara URI dan URL bersifat konseptual dan sebagian besar bersifat akademis, tetapi URI lebih baik didefinisikan dalam pengertian formal, dan mencakup kasus penggunaan yang lebih luas. Karena URL dan URI adalah / bukan hal yang sama, kelas baru diperkenalkan untuk mewakilinya, dengan metode URI.toURL dan URL.toURI untuk berpindah antara satu dan lainnya.
Di Java, perbedaan utama antara URL dan URI adalah bahwa URL memiliki ekspektasi dapat diselesaikan , sesuatu yang mungkin diinginkan aplikasi dari InputStream; URI diperlakukan lebih seperti thingamajig abstrak yang mungkin mengarah ke sesuatu yang dapat diselesaikan (dan biasanya memang demikian), tetapi apa artinya dan cara mencapainya lebih terbuka untuk konteks dan interpretasi.
Jalur (java.nio.file, 1.7)
Objek yang dapat digunakan untuk mencari file di sistem file. Ini biasanya akan mewakili jalur file yang bergantung pada sistem.
File API baru, yang diikonkan dalam antarmuka Path, memungkinkan fleksibilitas yang jauh lebih besar daripada yang dapat ditawarkan kelas File. Antarmuka Path adalah abstraksi dari kelas File , dan merupakan bagian dari New IO File API . Jika File selalu menunjuk ke "file" sebagaimana dipahami oleh platform host, Path lebih umum: Path mewakili file (sumber daya) dalam sistem file arbitrer .
Path menghilangkan ketergantungan pada konsep platform host dari sebuah file. Ini bisa berupa entri dalam file ZIP, file yang dapat dijangkau melalui FTP atau SSH-FS, representasi multi-root dari jalur kelas aplikasi, atau apa pun yang dapat direpresentasikan secara bermakna melalui antarmuka FileSystem dan drivernya, FileSystemProvider. Ini membawa kekuatan sistem file "pemasangan" ke dalam konteks aplikasi Java.
Platform host direpresentasikan melalui "sistem file default"; saat Anda menelepon File.toPath
, Anda mendapatkan Path pada sistem file default.
Sekarang, jika saya memiliki locator yang mereferensikan kelas atau paket dalam file jar, akankah keduanya (yaitu jalur string file) berbeda?
Tidak sepertinya. Jika file jar ada di sistem file lokal, Anda tidak boleh memiliki komponen kueri, jadi URL.getPath
dan URL.getFile
harus mengembalikan hasil yang sama. Namun, pilih yang Anda butuhkan: file-URL mungkin biasanya tidak memiliki komponen kueri, tapi saya yakin bisa menambahkannya.
Terakhir - dan yang paling penting - mengapa saya membutuhkan objek File; mengapa Sumber Daya (URL) tidak cukup?
URL mungkin tidak cukup karena File memberi Anda akses ke data housekeeping seperti izin (dapat dibaca, ditulis, dieksekusi), jenis file (apakah saya adalah direktori?), Dan kemampuan untuk mencari dan memanipulasi sistem file lokal. Jika ini adalah fitur yang Anda butuhkan, File atau Path menyediakannya.
Anda tidak memerlukan File jika Anda memiliki akses ke Path. Beberapa API lama mungkin memerlukan File.
(Dan apakah ada objek Resource?)
Tidak, tidak ada. Ada banyak hal yang dinamai seperti itu, tetapi itu bukan sumber daya dalam arti ClassLoader.getResource
.
Path
dan FileSystem dari NIO :)