Как получить абсолютный путь к файлу в папке / resources вашего проекта

95

Предположим стандартную настройку maven.

Скажем, в папке с ресурсами у вас есть файл abc.

В Java, как мне получить абсолютный путь к файлу, пожалуйста?

Джеймс Райцев
источник
Вы хотите написать плагин для Maven? Или вы хотите получить доступ к файлу во время выполнения вашей программы?
Gyro Gearless
По теме: stackoverflow.com/questions/8136891/…
Вадим
Есть три варианта решения, в зависимости от ситуации: stackoverflow.com/a/56327069/715269
Гангнус

Ответы:

73

Вы можете использовать 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 () из пути к классам.
Gyro Gearless
2
Что делать, если конечный пользователь запускает ваше приложение как исполняемый файл JAR? Тогда физического Файла вообще не будет. Это еще одна причина, по которой вы должны использовать getResource () и, например, открывать для него входной поток в зависимости от того, что вы хотите с ним делать.
Мэтью Уайз
6
Можно ли это убрать как правильный ответ? @Karol S ответил ниже - это должен быть правильный ответ (отсюда расхождение в голосовании)
DanGordon
3
Неверный ответ. Пожалуйста, обратитесь к ответу @Karol ниже
bhathiya-perera
168

Правильный способ, который действительно работает:

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())если бы захотели.
Майк
2
Я не понимаю, как это сработало для стольких людей без начального слэша:.getResource("/abc")
cahen
28

Вам нужно указать путь, начинающийся с /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();
Hett
источник
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сюда.

Вы можете вставить код в свой и увидеть имеющиеся у вас пути.

Гангнус
источник