Saya sedang melihat sepotong kode Java sekarang, dan itu mengambil jalur sebagai String dan mendapatkan URL-nya menggunakan URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);
, lalu memanggil String path = resource.getPath()
dan akhirnya dijalankan new File(path);
.
Oh, dan ada juga panggilan ke URL url = resource.toURI();
dan String file = resource.getFile()
.
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 menjadi hal yang sama, masing-masing ...
Perbedaan antara getFile()
dan getPath()
dijelaskan di sini: Apa perbedaan antara url.getFile () dan getpath ()? (Menariknya, mereka berdua tampaknya mengembalikan Strings, yang mungkin menambah banyak hal dalam pikiran saya ...)
Sekarang, jika saya memiliki locator yang mereferensikan kelas atau paket dalam file jar, akankah keduanya (yaitu jalur string file) berbeda?
resource.toString()
akan memberi Anda jar:file:/C:/path/to/my.jar!/com/example/
, setelah semua (perhatikan tanda seru).
Apakah perbedaan antara URI dan URL di Java yang sebelumnya tidak menyandikan spasi? Cf. File, URI, dan URL yang bentrok di Java (Jawaban ini menjelaskan perbedaan umum dan konseptual antara kedua istilah dengan cukup baik: URI mengidentifikasi dan URL menemukan; )
Terakhir - dan yang paling penting - mengapa saya membutuhkan File
objek; mengapa Resource ( URL
) tidak cukup? (Dan apakah ada objek Resource?)
Maaf jika pertanyaan ini agak tidak teratur; itu hanya mencerminkan kebingungan yang saya miliki ... :)
sumber
Path
dan FileSystem dari NIO :)URL
adalah buram - Anda menunjukkan itujar:file:
, yaitu sumber daya dalam.jar
arsip. Memukulnya menjadiFile
sangat tidak mungkin menghasilkan sesuatu yang berguna.Jawaban:
UPDATE 2017-04-12 Periksa jawaban JvR karena berisi penjelasan yang lebih lengkap dan tepat!
Harap dicatat bahwa saya tidak menganggap diri saya 100% kompeten untuk menjawab, namun berikut adalah beberapa komentar:
File
mewakili file atau direktori yang dapat diakses melalui sistem fileURL#getPath
adalah pengambil di bagian jalur URL (protocol://host/path?query
)URL#getFile
sesuai pengembalian JavaDocpath+query
Di Java,
URI
hanyalah sebuah struktur data untuk memanipulasi pengenal generik itu sendiri.URL
di sisi lain benar-benar pencari sumber daya dan menawarkan fitur untuk benar-benar membaca sumber daya melaluiURLStreamHandler
s terdaftar .URL dapat mengarah ke sumber daya sistem file dan Anda dapat membuat URL untuk setiap sumber daya sistem file dengan menggunakan
file://
protokol (karenanya hubunganFile
<->URL
).Ketahuilah juga bahwa itu
URL#getFile
tidak ada hubungannya denganjava.io.File
.Cukup. Hanya jika Anda ingin meneruskan sumber daya ke beberapa komponen yang hanya dapat bekerja dengan file, Anda harus mendapatkannya
File
. Namun tidak semua URL sumber daya dapat diubah menjadiFile
s.Dari sudut pandang JRE, itu hanya istilah. Beberapa kerangka kerja memberi Anda kelas seperti itu (misalnya Sumber Daya Spring ).
sumber
java.nio.file.Path
, yang pada dasarnya merupakan pengganti (Java 7+)java.io.File
, karena API yang terakhir tampaknya tidak dipikirkan dengan baik di masa-masa awal Java.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:
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)
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)
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)
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)
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.Tidak sepertinya. Jika file jar ada di sistem file lokal, Anda tidak boleh memiliki komponen kueri, jadi
URL.getPath
danURL.getFile
harus mengembalikan hasil yang sama. Namun, pilih yang Anda butuhkan: file-URL mungkin biasanya tidak memiliki komponen kueri, tapi saya yakin bisa menambahkannya.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.
Tidak, tidak ada. Ada banyak hal yang dinamai seperti itu, tetapi itu bukan sumber daya dalam arti
ClassLoader.getResource
.sumber
Jawaban Pavel Horal bagus.
Seperti yang dia katakan, kata "file" memiliki arti yang sama sekali berbeda (secara praktis tidak berhubungan) dalam
URL#getFile
vsjava.io.File
- mungkin itu bagian dari kebingungan.Hanya untuk menambahkan:
Sebuah sumber daya di Jawa adalah sebuah konsep abstrak, sumber data yang dapat dibaca. Lokasi (atau alamat) sumber daya diwakili di Jawa oleh sebuah
URL
objek.Sebuah sumber daya dapat sesuai dengan file biasa dalam filesystem lokal (khususnya, ketika yang
URL
dimulai denganfile://
). Tetapi sumber daya lebih umum (bisa juga beberapa file yang disimpan dalam jar, atau beberapa data untuk dibaca dari jaringan, atau dari memori, atau ...). Dan itu juga lebih terbatas, karena aFile
(selain hal lain selain file biasa: direktori, link) juga dapat dibuat dan ditulis.Ingat di Java,
File
objek tidak benar-benar mewakili "file" tetapi lokasi (nama lengkap, dengan jalur) dari file. Jadi,File
objek memungkinkan Anda untuk mencari (dan membuka) file, sebagaiURL
memungkinkan Anda untuk mengakses (dan membuka) sumber daya. (Tidak adaResource
kelas di Java untuk mewakili sumber daya, tetapi tidak ada kelas yang mewakili file! Sekali lagi:File
bukan file, ini adalah jalur file).sumber
Seperti yang saya pahami, Anda dapat mengategorikannya sebagai berikut:
Berbasis Web: URI dan URL.
Dan lokal: Resource, Path, dan Files
Akan lebih mudah jika mereka digabungkan menjadi satu kelas - sangat membingungkan: D
Saya harap ini membantu Anda :)
(Saya baru saja melihat-lihat dokumentasinya - lihat docs.oracle.com)
sumber
File adalah representasi abstrak dari suatu entitas di sistem file lokal.
Path umumnya berupa string yang menunjukkan lokasi file dalam sistem file. Biasanya tidak menyertakan nama file. Jadi c: \ documents \ mystuff \ stuff.txt akan memiliki path dengan nilai "C: \ documents \ mystuff" Jelas sekali format nama file dan path absolut akan sangat bervariasi dari sistem file ke sistem file.
URL adalah kumpulan URI dengan URL biasanya mewakili sumber daya yang dapat diakses melalui http. Saya rasa tidak ada aturan ketat tentang kapan sesuatu harus berupa URI vs URL. URI adalah string dalam bentuk "protocol: // resource-identifier" seperti bitcoin: // params, http://something.com?param=value . Kelas-kelas seperti URL umumnya membungkus string dan menyediakan metode utilitas yang tidak memiliki alasan untuk diberikan oleh String.
Tidak ada yang namanya Resource, setidaknya tidak dalam arti yang Anda bicarakan. Hanya karena sebuah metode bernama getResource tidak berarti ia mengembalikan objek bertipe Resource.
Pada akhirnya, cara terbaik untuk mencari tahu apa yang dilakukan metode Class adalah membuat instance-nya di kode Anda, memanggil metode tersebut, lalu melangkah dalam mode debug atau mengirimkan hasilnya ke System.out.
sumber