Java как указать путь к файлу из resources

Обновлено: 04.07.2024

Я пытаюсь получить путь к ресурсу, но мне не повезло.

это работает (как в IDE, так и с JAR), но таким образом я не могу получить путь к файлу, только содержимое файла:

Если я сделаю это:

результат: java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)

есть ли способ получить путь к файлу ресурса?

это умышленное. Содержимое "файла" может быть недоступно в виде файла. Помните, вы имеете дело с классами и ресурсами, которые могут быть частью файла jar или другого вида ресурса. Загрузчик классов не должен предоставлять дескриптор файла для ресурса, например файл jar не может быть развернут в отдельные файлы в файловой системе.

все, что вы можете сделать, получив java.io. File может быть сделано путем копирования потока во временный файл и делать то же самое, если java.io.файл абсолютно необходим.

при загрузке ресурса убедитесь, что вы заметили разницу между:

и

Я думаю, эта путаница вызывает большинство проблем при загрузке ресурса.

кроме того, когда вы загружаете изображение, его проще использовать getResourceAsStream() :

когда вам действительно нужно загрузить файл (без изображения) из архива JAR, вы можете попробовать это:

ответ на одну строку -

в принципе getResource метод дает URL. Из этого URL-адреса вы можете извлечь путь, вызвав toExternalForm()

ссылки:

getResource (), toExternalForm()

Я провел некоторое время возиться с этой проблемой, потому что ни одно решение я не нашел на самом деле работал, как ни странно! Рабочий каталог часто не является каталогом JAR, особенно если JAR (или любая программа, если на то пошло) запускается из меню Пуск под Windows. Так вот что я сделал, и это работает .класс файлы, которые запускаются из-за пределов флягу так же хорошо, как он работает за банку. (Я только протестировал его под Windows 7.)

Если netclient.p находится внутри файла JAR, у него не будет пути, потому что этот файл находится внутри другого файла. в этом случае лучший путь, который вы можете иметь, действительно file:/path/to/jarfile/bot.jar!/config/netclient.p .

вам нужно понять путь в файле jar.
Просто обратитесь к нему относительно. Так что если у вас есть файл (файл myfile.txt), расположенный в foo.баночка под \src\main\resources каталог (стиль maven). Вы бы назвали его так:

Если вы сбрасываете свою банку с помощью jar -tvf myjar.jar вы увидите вывод и относительный путь в файле jar, а также использовать прямые косые черты.

файл-это абстракция для файла в файловой системе, и файловые системы ничего не знают о том, что такое содержимое JAR.

попробуйте с URI, я думаю, что есть jar:// протокол, который может быть полезен для ваших целей.

Это тот же код от пользователя Tombart с потоком flush и close, чтобы избежать неполной временной копии содержимого файла из ресурса jar и иметь уникальные имена временных файлов.

в моем случае, я использовал объект URL вместо пути.

File

ресурс в classpath с помощью classloader

когда мне нужно прочитать содержимое, я могу использовать следующий код:

и вы можете получить доступ к содержимому с помощью InputStream.

следующий путь работал для меня: classpath:/path/to/resource/in/jar

это getSystemResourceAsStream это лучший вариант. Получая inputstream, а не файл или URL-адрес, работает в файле JAR и как автономный.

когда в файле jar ресурс находится абсолютно в иерархии пакетов (а не в иерархии файловой системы). Так что если у вас есть класс com.образец.Сладкая загрузка ресурса с именем"./неисполнение.conf "тогда имя ресурса указывается как" /com/example / default.конф".

но если это в банке, то это не файл .

В папке ressources (java / main / resources) вашего jar добавьте свой файл (мы предполагаем, что вы добавили xml-файл с именем импорт.xml), после чего вы вводите ResourceLoader Если вы используете весна, как ниже

внутри функции тура напишите ниже код для загрузки файла:

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

Вы хотите написать плагин для Maven? Или вы хотите получить доступ к файлу во время выполнения вашей программы?

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

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

Вы можете создать File объект и использовать getAbsolutePath метод:

Совет ограниченного использования, так как он полагается на рабочий каталог как на корень maven. И даже в этом случае вам лучше использовать target/classes/abc.txt ссылку на файл, поскольку это каноническое место, куда Maven помещает файлы ресурсов после обработки (например, плагин maven-resources мог выполнить подстановку свойств в abc.txt). Намного лучше использовать abc.txt через getResource () из пути к классам. Что делать, если конечный пользователь запускает ваше приложение как исполняемый файл JAR? Тогда физического Файла вообще не будет. Это еще одна причина, по которой вы должны использовать getResource () и, например, открывать для него входной поток в зависимости от того, что вы хотите с ним делать. Можно ли это убрать как правильный ответ? @Karol S ответил ниже - это должен быть правильный ответ (отсюда расхождение в голосовании) Неверный ответ. Пожалуйста, обратитесь к ответу @Karol ниже

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

Теперь не имеет значения, где физически находится файл в пути к классам, он будет найден, если ресурс на самом деле является файлом, а не записью JAR.

(Кажущееся очевидным new File(resource.getPath()) не работает для всех путей! Путь все еще закодирован в URL!)

Или, предположительно, вы могли бы просто сделать: new File(resource.toURI()).getAbsolutePath(); (т.е. я не думаю, что вам нужен объект Path?) Хороший совет о toURI (), это позволяет избежать пробелов на вашем пути, выходящих как% 20! Благодарность! У меня это почти сработало. Но мне пришлось внести одно изменение: YourClass.class.getClassLoader (). GetResource ("abc"); Вы могли бы поступить иначе, new File(YourClass.class.getResource("abc").toURI().getPath()) если бы захотели. Я не понимаю, как это сработало для стольких людей без начального слэша: .getResource("/abc")

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

Создайте экземпляр classLoader нужного вам класса, тогда вы сможете легко получить доступ к файлам или ресурсам. теперь вы получаете доступ к пути, используя getPath() метод этого класса.

Чтобы вернуть файл или путь к файлу

На нашем пути к абсолютному пути есть две проблемы:

  1. Найденное место размещения будет не там, где лежат исходные файлы, а там, где сохранен класс. И папка ресурсов почти наверняка будет где-то в исходной папке проекта.
  2. Те же функции для получения ресурса работают по-разному, если класс выполняется в подключаемом модуле или в пакете непосредственно в рабочей области.

Следующий код даст нам все полезные пути:

Здесь исследуются обе функции, которые можно использовать для локализации папки ресурсов. Что касается class , его можно получить как статически, так и динамически.

Если проекта нет в подключаемом модуле, код при запуске в JUnit напечатает:

Итак, чтобы добраться до src / rest / resources, мы должны перемещаться вверх и вниз по дереву файлов. Можно использовать оба метода. Обратите внимание, мы не можем использовать getResource(resourceFolderName) , потому что эта папка не находится в целевой папке. Надеюсь, никто не кладет ресурсы в созданные папки.

Если класс находится в пакете, который находится в плагине, результат того же теста будет:

Итак, мы снова должны идти вверх и вниз по дереву папок.

Наиболее интересен случай, когда пакет запускается в плагине. В качестве теста плагина JUnit для нашего примера. Результат:

Здесь мы можем получить абсолютный путь, только объединив результаты обеих функций. И этого мало. Между ними мы должны поместить локальный путь к месту, где находятся пакеты классов, относительно папки плагина. Возможно, вам придется что-то вставить как src или src/test/resource сюда.

у меня есть этот код, который не работал. Он жалуется "нет такого файла или каталога".

Я также пробовал это

это также не работает. Он возвращается null . Я использую Maven для создания своего проекта.

если выше не работает, различные проекты были добавлены в следующий класс: ClassLoaderUtil 1 (код здесь). 2

вот несколько примеров того, как этот класс используется:

IIRC getResourceAsStream() по умолчанию относится к пакету класса.

вот одно быстрое решение с использованием гуавы:

попробуйте течь коды на Spring project

или на не весеннем проекте

Если вы используете context ClassLoader для поиска ресурса, это определенно будет стоить производительности приложения.

теперь я иллюстрирую исходный код для чтения шрифта из каталога созданных ресурсов maven,

scr / main / resources / calibril.ttf

enter image description here

Он работал для меня, и надеюсь, что весь исходный код также поможет вам, наслаждайтесь!

работает ли код, когда не выполняется jar Maven-build, например, при запуске из IDE? Если это так, убедитесь, что файл действительно включен в jar. Папка resources должна быть включена в файл pom, в <build><resources> .

getResource () отлично работал с файлами ресурсов, размещенными в src/main/resources только. Чтобы получить файл, который находится на пути, отличном от src/main/resources сказать src/test/java вам нужно создать его exlicitly.

следующий пример может помочь вам

Я решил эту проблему путем добавления мой Java Build Path

enter image description here

Я заставляю его работать без какой-либо ссылки на "class" или "ClassLoader".

предположим, у нас есть три сценария с расположением примера файла.файл " и ваш рабочий каталог (где выполняется ваше приложение) - home/mydocuments/program/projects/myapp:

a) потомок вложенной папки в рабочий каталог: myapp/res/files / пример.файл

b) подпапка, не являющаяся потомком рабочего каталога: проекты/файлы/пример.файл

b2) другая подпапка не является потомком рабочего каталога: программа / файлы / пример.файл

c) корневая папка: главная/mydocuments/файлы / пример.файл (Linux; в Windows заменить home / на C:)

1) получить правильный путь: а) String path = "res/files/example.file"; б) String path = "../projects/files/example.file" Б2) String path = "../../program/files/example.file" c) String path = "/home/mydocuments/files/example.file"

в основном, если это корневая папка, начните путь с ведущей косой черты. Если это подпапка, перед именем пути не должно быть косой черты. Если подпапка не является потомком рабочего каталога, который вы должны cd к нему использовать"../". Это говорит системе подняться на одну папку.

Проблема чтения пути к файлу ресурсов проекта Java в ресурсах

Обычно при чтении файлов по определенному пути в проекте Java вы можете использовать абсолютные и относительные пути.Об абсолютных путях нечего сказать.Относительные пути - это пути относительно текущего класса. Способ чтения файлов в локальном проекте и на сервере отличается. В качестве примера возьмем файл конфигурации, показанный на следующем рисунке.


Чтение файлов ресурсов локально

Необходимо прочитать файл конфигурации в свойствах в классе java, вы можете использоватьфайлСпособ чтения:

При запуске в eclipse (не развернутом на сервере) файл можно прочитать.

Сервер (Tomcat) читает файлы ресурсов

Метод 1: используйте поток + свойства

При развертывании проекта в Tomcat в соответствии с описанным выше методом возникнет исключение, что путь к файлу не может быть найден. После поиска данных становится известно, что когда проект Java упаковывается и развертывается в Tomcat, путь к свойствам изменяется на верхний уровень (под классами), который определяется структурой проекта Maven. Для веб-проектов, созданных Maven, основной код размещается по пути src / main / java, а ресурсы - по пути src / main / resources. При сборке как военный пакет основной код и файлы ресурсов будут помещены в папку классов. :


И в это время вам нужно использоватьРучейИнформацию в файле конфигурации можно легко получить, загрузив его через класс Properties в JDK, как показано ниже:

Косая черта перед свойствами - это общий путь верхнего уровня относительно вызывающего класса.

Метод 2: использование аннотаций Spring

Если в проекте используется Spring, информацию о конфигурации можно получить с помощью аннотаций, но файл конфигурации необходимо просканировать в файле конфигурации Spring, прежде чем информация о конфигурации может быть помещена в контекст.

Затем вы можете использовать @Value в программе, чтобы получить значение свойства в файле свойств, как показано ниже:

Метод третий: принять конфигурацию Spring

Вы также можете прочитать значения свойств в файле конфигурации Spring и назначить переменные-члены класса

Читайте также: