Saya ingin membaca sumber dari dalam toples saya seperti ini:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
dan itu berfungsi dengan baik ketika menjalankannya di Eclipse, tetapi jika saya mengekspornya ke stoples itu menjalankannya ada IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
dan saya benar-benar tidak tahu mengapa tetapi dengan beberapa pengujian saya menemukan jika saya berubah
file = new File(getClass().getResource("/file.txt").toURI());
untuk
file = new File(getClass().getResource("/folder/file.txt").toURI());
maka itu bekerja sebaliknya (itu bekerja di toples tetapi tidak gerhana).
Saya menggunakan Eclipse dan folder dengan file saya ada di folder kelas.
getResourceAsStream
masih solusi sederhana dan lebih portabel untuk masalah ini.Jawaban:
Daripada mencoba menangani sumber daya sebagai File, minta ClassLoader untuk mengembalikan InputStream untuk sumber daya alih-alih melalui getResourceAsStream :
Selama
file.txt
sumber daya tersedia di classpath maka pendekatan ini akan bekerja dengan cara yang sama terlepas dari apakahfile.txt
sumber daya ada diclasses/
direktori atau di dalam ajar
.The
URI is not hierarchical
terjadi karena URI untuk sumber daya dalam file jar akan terlihat seperti ini:file:/example.jar!/file.txt
. Anda tidak dapat membaca entri dalamjar
(zip
file) seperti itu adalah File lama biasa .Ini dijelaskan dengan baik oleh jawaban untuk:
sumber
InputStream
ada (sepertiFile.exists()
) sehingga game saya dapat mengetahui apakah akan menggunakan file default atau tidak. Terima kasih.getClass().getResource("**/folder**/file.txt")
membuatnya berfungsi adalah karena saya punya folder itu di direktori yang sama dengan toples saya :).getResourceAsStream
mengembalikan nol jika sumber daya tidak ada sehingga bisa menjadi tes "ada" Anda.Untuk mengakses file dalam toples Anda memiliki dua opsi:
Tempatkan file dalam struktur direktori yang cocok dengan nama paket Anda (setelah mengekstrak file .jar, itu harus berada di direktori yang sama dengan file .class), kemudian mengaksesnya menggunakan
getClass().getResourceAsStream("file.txt")
Tempatkan file di root (setelah mengekstrak file .jar, itu harus di root), lalu akses menggunakan
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
Opsi pertama mungkin tidak berfungsi ketika jar digunakan sebagai plugin.
sumber
Saya punya masalah ini sebelumnya dan saya membuat jalan mundur untuk memuat. Pada dasarnya cara pertama bekerja di dalam file .jar dan cara kedua berfungsi di dalam gerhana atau IDE lainnya.
sumber
Sampai sekarang (Desember 2017), ini adalah satu-satunya solusi yang saya temukan yang berfungsi baik di dalam maupun di luar IDE.
Gunakan PathMatchingResourcePatternResolver
Catatan: ini juga berfungsi di spring-boot
Dalam contoh ini saya membaca beberapa file yang terletak di src / main / resources / my_folder :
sumber
Masalahnya adalah bahwa perpustakaan pihak ketiga tertentu memerlukan nama path file daripada input stream. Sebagian besar jawaban tidak membahas masalah ini.
Dalam hal ini, satu solusi adalah menyalin konten sumber daya ke file sementara. Contoh berikut menggunakan jUnit
TemporaryFolder
.sumber
Jika Anda ingin membaca sebagai file, saya yakin masih ada solusi serupa:
sumber
file:
URL.Pastikan Anda bekerja dengan pemisah yang benar. Saya mengganti semua
/
di jalur relatif denganFile.separator
. Ini bekerja dengan baik di IDE, namun tidak bekerja di build JAR.sumber
Saya pikir ini harusnya berfungsi di java juga. Kode berikut yang saya gunakan menggunakan kotlin.
sumber
Saya telah menemukan perbaikan
Ganti "Main" dengan kelas java tempat Anda memasukkannya. Ganti "path" dengan path di dalam file jar.
misalnya, jika Anda memasukkan State1.txt dalam paket com.issac.state, lalu ketikkan lintasan sebagai "/ com / issac / state / State1" jika Anda menjalankan Linux atau Mac. Jika Anda menjalankan Windows maka ketikkan path sebagai "\ com \ issac \ state \ State1". Jangan tambahkan ekstensi .txt ke file kecuali pengecualian File tidak ditemukan.
sumber
Anda dapat menggunakan pemuat kelas yang akan membaca dari classpath sebagai jalur ROOT (tanpa "/" di awal)
sumber
Jika Anda menggunakan pegas, maka Anda dapat menggunakan metode berikut untuk membaca file dari src / main / resources:
sumber
Untuk beberapa alasan
classLoader.getResource()
selalu mengembalikan nol ketika saya menggunakan aplikasi web ke WildFly 14. mendapatkan classLoader darigetClass().getClassLoader()
atauThread.currentThread().getContextClassLoader()
mengembalikan null.getClass().getClassLoader()
API API mengatakan,"Mengembalikan pemuat kelas untuk kelas. Beberapa implementasi mungkin menggunakan null untuk mewakili pemuat kelas bootstrap. Metode ini akan mengembalikan nol dalam implementasi seperti itu jika kelas ini dimuat oleh pemuat kelas bootstrap."
mungkin jika Anda menggunakan WildFly dan aplikasi web Anda coba ini
request.getServletContext().getResource()
mengembalikan url sumber daya. Di sini permintaan adalah objek dari ServletRequest.sumber
Kode di bawah ini berfungsi dengan Spring boot (kotlin):
sumber