Saya bertanya-tanya apa perbedaan antara Class.getResource()
dan ClassLoader.getResource()
?
sunting: Saya terutama ingin tahu apakah ada caching yang terlibat pada level file / direktori. Seperti pada "apakah daftar direktori di-cache dalam versi Kelas?"
AFAIK pada dasarnya harus melakukan hal yang sama, tetapi tidak:
getClass().getResource()
getClass().getClassLoader().getResource()
Saya menemukan ini ketika mengutak-atik beberapa kode pembuatan laporan yang membuat file baru WEB-INF/classes/
dari file yang ada di direktori itu. Ketika menggunakan metode dari Class, saya bisa menemukan file yang ada di deployment menggunakan getClass().getResource()
, tetapi ketika mencoba untuk mengambil file yang baru dibuat, saya menerima objek nol. Menjelajahi direktori dengan jelas menunjukkan bahwa file baru ada di sana. Nama file diawali dengan garis miring ke depan seperti pada "/myFile.txt".
The ClassLoader
versi getResource()
di sisi lain menemukan file yang dihasilkan. Dari pengalaman ini tampaknya ada semacam caching dari daftar direktori yang terjadi. Apakah saya benar, dan jika demikian, di mana ini didokumentasikan?
Dari dokumentasi API padaClass.getResource()
Menemukan sumber daya dengan nama yang diberikan. Aturan untuk mencari sumber daya yang terkait dengan kelas yang diberikan diimplementasikan oleh pemuat kelas mendefinisikan kelas. Metode ini mendelegasikan ke pemuat kelas objek ini. Jika objek ini dimuat oleh bootstrap class loader, metode mendelegasikan ke ClassLoader.getSystemResource (java.lang.String).
Bagi saya, ini berbunyi "Class.getResource benar-benar memanggil getResource ()" classloadernya sendiri. Yang akan sama dengan melakukan getClass().getClassLoader().getResource()
. Tapi jelas tidak. Bisakah seseorang tolong berikan saya iluminasi tentang hal ini?
sumber
Class.getResource
dapat mengambil nama sumber daya "relatif", yang diperlakukan relatif terhadap paket kelas. Atau Anda dapat menentukan nama sumber daya "absolut" dengan menggunakan garis miring terkemuka. Jalur sumber daya Classloader selalu dianggap mutlak.Jadi yang berikut ini pada dasarnya setara:
Demikian juga ini (tetapi berbeda dari yang di atas):
sumber
this.getClass().getClassLoader().getResource("/");
mengembalikan null? Seharusnya tidak sama denganthis.getClass().getClassLoader().getResource(".");
Panggilan pertama mencari relatif ke
.class
file sedangkan pencarian terakhir relatif terhadap root classpath.Untuk men-debug masalah seperti itu, saya mencetak URL:
sumber
getClassLoader().getResource("/...")
selalu kembalinull
- classloader tidak menghapus yang memimpin/
dari jalan, sehingga pencarian selalu gagal. HanyagetClass().getResource()
menangani permulaan/
sebagai jalur absolut relatif terhadap classpath.Harus mencarinya dalam spesifikasi:
Class.getResource (sumber daya String)
ClassLoader.getResource (Sumber daya string)
GetResource () - dokumentasi menyatakan perbedaan:
sumber
Semua jawaban di sekitar sini, serta jawaban dalam pertanyaan ini , menyarankan bahwa memuat URL absolut, seperti "/foo/bar.properties" diperlakukan sama oleh
class.getResourceAsStream(String)
danclass.getClassLoader().getResourceAsStream(String)
. Ini BUKAN kasusnya, setidaknya tidak dalam konfigurasi / versi Tomcat saya (saat ini 7.0.40).Maaf, saya sama sekali tidak memiliki penjelasan yang memuaskan, tapi saya kira kucing jantan melakukan trik kotor dan sihir hitamnya dengan classloader dan menyebabkan perbedaan. Saya selalu menggunakan
class.getResourceAsStream(String)
di masa lalu dan tidak punya masalah.PS: Saya juga memposting ini di sini
sumber
Class.getResources
akan mengambil sumber daya oleh classloader yang memuat objek. SementaraClassLoader.getResource
akan mengambil sumber daya menggunakan classloader yang ditentukan.sumber
Saya mencoba membaca dari input1.txt yang ada di dalam salah satu paket saya bersama dengan kelas yang mencoba membacanya.
Karya-karya berikut:
Bagian terpenting adalah menelepon
getPath()
jika Anda ingin nama jalur yang benar dalam format String. JANGAN GUNAKANtoString()
karena akan menambahkan beberapa teks format tambahan yang akan BENAR-BENAR MESS UP fileName (Anda dapat mencobanya dan melihat hasil cetaknya).Menghabiskan 2 jam men-debug ini ... :(
sumber
FileReader
atauFileInputStream
tidak dapat digunakan untuk mengaksesnya. Jawabannya tidak benar.