Як отримати абсолютний шлях до файлу в папці / resources вашого проекту


93

Припустимо стандартне налаштування maven.

Скажімо, у вашій папці ресурсів є файл abc.

На Java, як я можу отримати абсолютний шлях до файлу, будь ласка?


Ви хочете написати плагін Maven? Або ви хочете отримати доступ до файлу під час запуску вашої програми?
Гіроскоп Gearless


Є три варіанти вирішення, в залежності від ситуації: stackoverflow.com/a/56327069/715269
Гангнус

Відповіді:


72

Ви можете використовувати ClassLoader.getResourceметод, щоб отримати правильний ресурс.

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

АБО

Хоча це може не працювати весь час, більш просте рішення -

Ви можете створити Fileоб'єкт і використовувати getAbsolutePathметод:

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

8
Порада обмеженого використання, оскільки вона покладається на робочий каталог, який буде коренем maven. І навіть тоді вам краще скористатися target/classes/abc.txtпосиланням на файл, оскільки це канонічне місце, куди Maven поміщає файли ресурсів після обробки (наприклад, плагін maven-resources міг здійснити заміну властивостей на abc.txt). Набагато краще використовувати abc.txt через getResource () із шляху до класу.
Гіроскоп Gearless

2
Що робити, якщо кінцевий користувач запускає вашу програму як виконуваний файл JAR? Тоді фізичного файлу взагалі не буде. Це ще одна причина, чому ви повинні використовувати getResource () і, наприклад, відкрити вхідний потік до нього, залежно від того, що ви хочете з ним робити.
Matthew Wise

6
Чи можна це видалити як правильну відповідь? @Karol S відповів нижче - це повинна бути правильна відповідь (звідси розбіжність)
DanGordon

3
Неправильну відповідь. Будь ласка, зверніться до відповіді нижче @Karol
bhathiya-perera

167

Правильний спосіб, який насправді працює:

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

Зараз не має значення, де фізично знаходиться файл у шляху до класу, він буде знайдений до тих пір, поки ресурс насправді є файлом, а не записом JAR.

(Здається, очевидне new File(resource.getPath())працює не для всіх шляхів! Шлях все ще закодований за URL-адресою!)


5
Або, мабуть, ви могли б просто зробити: new File(resource.toURI()).getAbsolutePath();(тобто я не думаю, що вам потрібен об’єкт Path?)
Ден Кінг

1
Хороша порада щодо toURI (), це дозволяє уникнути пропусків на вашому шляху як% 20!
Метью Мудрий

29
Дякую! Це майже спрацювало для мене. Але мені довелося зробити одну зміну: YourClass.class.getClassLoader (). GetResource ("abc");
yngwietiger

Ви можете по черзі робити, new File(YourClass.class.getResource("abc").toURI().getPath())якщо хочете.
Mike Rylander

2
Я не розумію, як це працювало для такої кількості людей без початкової косої риски:.getResource("/abc")
cahen

28

Вам потрібно вказати шлях, починаючи з /

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

12

Створіть екземпляр classLoader потрібного вам класу, тоді ви зможете легко отримати доступ до файлів або ресурсів. тепер ви отримуєте доступ до шляху за допомогою getPath()методу цього класу.

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

1

Щоб повернути файл або шлях до нього

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

На нашому шляху до абсолютного шляху є дві проблеми:

  1. Знайдене розташування буде не там, де лежать вихідні файли, а там, де клас зберігається. І папка ресурсів майже напевно лежить десь у вихідній папці проекту.
  2. Ті самі функції для отримання ресурсу працюють по-різному, якщо клас працює в плагіні або в пакеті безпосередньо в робочій області.

Наступний код надасть нам усі корисні шляхи:

    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);

Тут досліджуються обидві функції, які можуть бути використані для локалізації папки ресурсів. Що стосується class, його можна отримати будь-яким способом, статичним або динамічним.


Якщо проекту немає в плагіні, код, який запускається в JUnit, надрукує:

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

Отже, щоб перейти до src / rest / resources, нам слід підніматися вгору та вниз по дереву файлів. Можна використовувати обидва методи. Зверніть увагу, ми не можемо використовувати getResource(resourceFolderName), оскільки ця папка відсутня у цільовій папці. Сподіваюся, ніхто не вкладає ресурси у створені папки.


Якщо клас знаходиться в пакеті, який знаходиться в плагіні, результатом цього ж тесту буде:

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

Отже, знову нам слід підніматися вгору-вниз по дереву папок.


Найцікавішим є випадок, коли пакет запускається в плагіні. Як тест плагіна JUnit, для нашого прикладу. Результат:

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

Тут ми можемо отримати абсолютний шлях, лише поєднуючи результати обох функцій. І цього недостатньо. Між ними слід помістити локальний шлях до місця, де знаходяться пакети класів, відносно папки плагіна. Можливо, вам доведеться вставити щось як srcабоsrc/test/resource сюди.

Ви можете вставити код у свій і побачити шляхи, які у вас є.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.