Cara mendapatkan jalur absolut ke file di / folder sumber proyek Anda


95

Asumsikan pengaturan maven standar.

Katakanlah di folder resource Anda, Anda memiliki file abc.

Di Java, bagaimana saya bisa mendapatkan path absolut ke file tersebut?


Apakah Anda ingin menulis plugin Maven? Atau apakah Anda ingin mengakses file saat program Anda dijalankan?
Gyro Gearless


Ada tiga varian solusi, tergantung situasinya: stackoverflow.com/a/56327069/715269
Gangnus

Jawaban:


73

Anda dapat menggunakan ClassLoader.getResourcemetode untuk mendapatkan sumber daya yang benar.

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

ATAU

Meskipun ini mungkin tidak selalu berhasil, solusi yang lebih sederhana -

Anda dapat membuat Fileobjek dan menggunakan getAbsolutePathmetode:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();

8
Saran penggunaan terbatas, karena bergantung pada direktori kerja sebagai root maven. Dan meskipun demikian, Anda sebaiknya menggunakan target/classes/abc.txtuntuk mereferensikan file, karena ini adalah tempat kanonik tempat Maven meletakkan file resource setelah diproses (misalnya, plugin maven-resources mungkin telah melakukan substitusi properti di abc.txt). Jauh lebih baik menggunakan abc.txt melalui getResource () dari classpath.
Gyro Gearless

2
Bagaimana jika pengguna akhir menjalankan aplikasi Anda sebagai JAR yang dapat dijalankan? Maka tidak akan ada File fisik sama sekali. Ini adalah alasan lain mengapa Anda harus menggunakan getResource (), dan misalnya membuka aliran input padanya tergantung pada apa yang ingin Anda lakukan dengannya.
Matthew Wise

6
Bisakah ini dihapus sebagai jawaban yang benar? @Karol S menjawab di bawah ini - itu harus menjadi jawaban yang benar (karenanya perbedaan
suara positif

3
Jawaban yang salah. Silakan lihat jawaban di bawah ini oleh @Karol
bhiya-perera

168

Cara yang benar yang benar-benar berhasil:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

Tidak masalah sekarang di mana file di classpath secara fisik berada, itu akan ditemukan selama sumber daya sebenarnya adalah file dan bukan entri JAR.

(Yang tampaknya jelas new File(resource.getPath())tidak berfungsi untuk semua jalur! Jalur tersebut masih dikodekan URL!)


5
Atau mungkin Anda hanya bisa melakukan: new File(resource.toURI()).getAbsolutePath();(yaitu saya tidak berpikir Anda membutuhkan objek Path?)
Dan King

1
Tip bagus tentang toURI (), ini menghindari spasi di jalur Anda yang keluar sebagai% 20!
Matthew Wise

29
Terima kasih! Ini hampir berhasil bagi saya. Tetapi saya harus membuat satu perubahan: YourClass.class.getClassLoader (). GetResource ("abc");
yngwietiger

Anda bisa melakukannya new File(YourClass.class.getResource("abc").toURI().getPath())jika Anda mau.
Mike Rylander

2
Saya tidak mengerti bagaimana ini berhasil untuk banyak orang tanpa garis miring:.getResource("/abc")
cahen

28

Anda perlu menentukan jalur mulai dari /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();

12

Buat instance classLoader dari kelas yang Anda butuhkan, lalu Anda dapat mengakses file atau sumber daya dengan mudah. sekarang Anda mengakses jalur menggunakan getPath()metode kelas itu.

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);

1

Untuk mengembalikan file atau jalur file

URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path

0

Ada dua masalah dalam perjalanan kita menuju jalan absolut:

  1. Penempatan yang ditemukan bukan di tempat file sumber berada, tetapi di mana kelas disimpan. Dan folder sumber daya hampir pasti akan berada di suatu tempat di folder sumber proyek.
  2. Fungsi yang sama untuk mengambil sumber daya berfungsi secara berbeda jika kelas dijalankan di plugin atau dalam paket langsung di ruang kerja.

Kode berikut akan memberi kita semua jalur yang berguna:

    URL localPackage = this.getClass().getResource("");
    URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
    String localDir = localPackage.getPath();
    String loaderDir = urlLoader.getPath();
    System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);

Di sini kedua fungsi yang dapat digunakan untuk pelokalan folder sumber daya diteliti. Adapun class, itu bisa didapat dengan cara apa pun, secara statis atau dinamis.


Jika proyek tidak ada di plugin, kode jika dijalankan di JUnit, akan mencetak:

loaderDir = /C:.../ws/source.dir/target/test-classes/
 localDir = /C:.../ws/source.dir/target/test-classes/package/

Jadi, untuk masuk ke src / rest / resources kita harus naik dan turun pohon file. Kedua metode tersebut dapat digunakan. Perhatikan, kami tidak dapat menggunakan getResource(resourceFolderName), karena folder itu tidak ada di folder target. Tidak ada yang menempatkan sumber daya di folder yang dibuat, saya harap.


Jika kelas ada dalam paket yang ada di plugin, keluaran dari pengujian yang sama akan menjadi:

loaderDir = /C:.../ws/plugin/bin/
 localDir = /C:.../ws/plugin/bin/package/

Jadi, sekali lagi kita harus naik dan turun pohon folder.


Yang paling menarik adalah kasus ketika paket diluncurkan di plugin. Sebagai pengujian plugin JUnit, untuk contoh kami. Outputnya adalah:

loaderDir = /C:.../ws/plugin/
 localDir = /package/

Di sini kita bisa mendapatkan jalur absolut hanya dengan menggabungkan hasil dari kedua fungsi tersebut. Dan itu tidak cukup. Di antara mereka, kita harus meletakkan jalur lokal tempat paket kelas berada, secara relatif ke folder plugin. Mungkin, Anda harus memasukkan sesuatu sebagai srcatau di src/test/resourcesini.

Anda dapat memasukkan kode ke milik Anda dan melihat jalur yang Anda miliki.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.