Java как указать путь к файлу из resources
Перейти к содержимому

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

  • автор:

Урок 3: Работа с ресурсами

Этот урок освещает работу с ресурсами и основан на оригинальной документации §6. Resources.

Что вам потребуется

  • Любимый текстовый редактор или IDE
  • JDK 7 и выше
  • Maven 3.0+
  • Исходный код предыдущего урока

Настройка проекта

Прежде чем вы начнете изучать этот урок, вам необходимо создать класс lessons.starter.ResourceStarter .

Введение

Стандартный Java-класс java.net.URL и стандартные обработчки различных URL префиксов к сожалению не во всём достаточно пригодны для доступа к низкоуровневым ресурсам. К примеру, нет стандартизированных реализаций URL , которые могут быть использованы для доступа к ресурсам, которые необходимо получить из classpath, либо ServletContext . Можно зарегистрировать новые обработчики для конкретных URL префиксов, но это довольно сложная задача, а интерфейс URL все ещё недостаточно функционален.

Spring предоставляет интерфейс Resource , более совместимый для низкоуровнего доступа.

public interface Resource extends InputStreamSource < boolean exists(); boolean isOpen(); URL getURL() throws IOException; File getFile() throws IOException; Resource createRelative(String relativePath) throws IOException; String getFilename(); String getDescription(); //. >
public interface InputStreamSource

Интерфейс Resource используется и в самом Spring в качестве типа аргументов во многих методах, где необходимы ресурсы. Другие методы принимают в качестве аргументов строковые значения, которые в конечном счете используются для получения ресурсов. Важно понимать, что реализации интерфейса Resource не заменяют функциональность, а являются «оберткой». Например, URLResource является «оберткой» для URL .

Встроенные реализации

Из реализаций интерфейса Resource , которые входят в состав Spring, стоит выделить следующие:

  • UrlResource — является оберткой для java.net.URL и может быть использован для доступа к любому объекту по его URL, например, файлы, HTTP или FTP ресурс и др., либо через строковое представление с соответветствующими префиксами classpath: , file: , http: , ftp: и др.
  • ClassPathResource — представляет ресурс, который может быть получен из classpath и поддерживает ресурсы как java.io.File , если они расположены в файловой системе, а не в jar
  • FileSystemResource — реализация для обработки java.io.File . Поддерживает как File , так и URL
  • ServletContextResource — реализация для обработки ServletContext ресурсов относительно корневой директории web-приложения. Поддерживает потоковый и к URL доступ. Доступ к java.io.File возможен, когда web-приложение развернуто и ресурс физически находится в файловой системе
  • InputStreamResource — реализация для обработки InputStream . Должен использоваться только тогда, когда нет доступных соответствующих реализаций интерфейса Resource или нет возможности использовать более предпочтительный вариант ByteArrayResource
  • ByteArrayResource — реализация для обработки массива байтов. Полезен для загрузки контента из любого массива байтов, не прибегая к использованию InputStreamResource

Получение ресурсов

ResourceLoader

Интерфейс ResourceLoader предназначен для реализации возврата, т.е. загрузки, экземпляров Resource .

public interface ResourceLoader

Все контексты приложения реализуют данный интерфейс. Когда вы вызываете метод getResource() в определенном контексте приложения без указания префикса, то вы получите тот тип Resource , который соответствует контексту. В качестве демонстрации, можно запустить метод src/main/java/lessons/starter/ResourceStarter#printClassResourcesByContextNoPrefix() . В методе src/main/java/lessons/starter/ResourceStarter#printClassResourcesByContextWithPrefix() на консоль отбражаются подобные результаты, но ресурс передается уже с префиксом.

public class ResourceStarter < public static final Logger LOGGER = LogManager.getLogger(ResourceStarter.class); public static void main(String[] args) throws IOException < LOGGER.info("Starting resources. "); ResourceStarter starter = new ResourceStarter(); starter.printClassResourcesByContextNoPrefix(); starter.printClassResourcesByContextWithPrefix(); >public void printClassResourcesByContextNoPrefix() < LOGGER.info("*******printClassResourcesByContextNoPrefix**********"); ApplicationContext context = new AnnotationConfigApplicationContext(); Resource resource = context.getResource("resources/log4j.properties"); LOGGER.info("AnnotationConfigApplicationContext: " + resource.getClass().getSimpleName()); context = new ClassPathXmlApplicationContext(); resource = context.getResource("resources/log4j.properties"); LOGGER.info("ClassPathXmlApplicationContext: " + resource.getClass().getSimpleName()); context = new FileSystemXmlApplicationContext(); resource = context.getResource("resources/log4j.properties"); LOGGER.info("FileSystemXmlApplicationContext: " + resource.getClass().getSimpleName()); LOGGER.info("****************************************************"); >public void printClassResourcesByContextWithPrefix() < LOGGER.info("*******printClassResourcesByContextWithPrefix*******"); ApplicationContext context = new AnnotationConfigApplicationContext(); Resource resource = context.getResource("file:resources/log4j.properties"); LOGGER.info("file: " + resource.getClass().getSimpleName()); resource = context.getResource("http://spring.io/img/favicon.png"); LOGGER.info("http: " + resource.getClass().getSimpleName()); resource = context.getResource("classpath:resources/log4j.properties"); LOGGER.info("classpath: " + resource.getClass().getSimpleName()); LOGGER.info("****************************************************"); >>

ResourceLoaderAware

Интерфейс ResourceLoaderAware обеспечивает объект ссылкой на ResourceLoader .

public interface ResourceLoaderAware

Если класс реализует интерфейс ResourceLoaderAware и развернут в контексте приложения, например, как бин, то при его сборке контекст приложения будет вызывать метод setResourceLoader() и передавать соответствующий ResourceLoader , в зависимости от типа контекста.

Получение ресурса по его пути

Если ваш контекст ClassPathXmlApplicationContext , то вы можете получить ресурс по его пути с указанием префикса classpath: или без него с учетом его местоположения в classpath. Если же вам необходимо получить ресурс по его полному пути, то вам необходимо указать префикс file: , либо ваш контекст должен быть типа FileSystemXmlApplicationContext . В качестве демонстрации, можно запустить метод src/main/java/lessons/starter/ResourceStarter#resourcePath() .

public class ResourceStarter < public static final Logger LOGGER = LogManager.getLogger(ResourceStarter.class); public static void main(String[] args) throws IOException < //. starter.resourcePath(); >public void resourcePath() throws IOException < LOGGER.info("*****************resourcePath()*********************"); LOGGER.info("context = new ClassPathXmlApplicationContext()"); ApplicationContext context = new ClassPathXmlApplicationContext(); Resource resource = context.getResource("log4j.properties"); LOGGER.info("log4j.properties exist: " + resource.getFile().exists()); // resource = context.getResource("src/main/resources/log4j.properties"); // LOGGER.info("log4j.properties exist: " + resource.getFile().exists()); //IOException resource = context.getResource("file:src/main/resources/log4j.properties"); LOGGER.info("file:src/main/resources/log4j.properties exist: " + resource.getFile().exists()); resource = context.getResource("log/log.txt"); LOGGER.info("log/log.txt exist: " + resource.getFile().exists()); resource = context.getResource("classpath:log/log.txt"); LOGGER.info("classpath:log/log.txt exist: " + resource.getFile().exists()); resource = context.getResource("file:log.txt"); LOGGER.info("file:log.txt exist: " + resource.getFile().exists()); resource = context.getResource("file:log/log.txt"); LOGGER.info("file:log/log.txt exist: " + resource.getFile().exists()); resource = context.getResource("file:src/main/resources/log/log.txt"); LOGGER.info("file:src/main/resources/log/log.txt exist: " + resource.getFile().exists()); LOGGER.info("context = new FileSystemXmlApplicationContext()"); context = new FileSystemXmlApplicationContext(); resource = context.getResource("log4j.properties"); LOGGER.info("log4j.properties exist: " + resource.getFile().exists()); resource = context.getResource("src/main/resources/log4j.properties"); LOGGER.info("src/main/resources/log4j.properties exist: " + resource.getFile().exists()); resource = context.getResource("log/log.txt"); LOGGER.info("log/log.txt exist: " + resource.getFile().exists()); resource = context.getResource("classpath:log/log.txt"); LOGGER.info("classpath:log/log.txt exist: " + resource.getFile().exists()); resource = context.getResource("file:log.txt"); LOGGER.info("file:log.txt exist: " + resource.getFile().exists()); resource = context.getResource("file:log/log.txt"); LOGGER.info("file:log/log.txt exist: " + resource.getFile().exists()); LOGGER.info("****************************************************"); >>

Итог

Несмотря на небольшой объем урока, вы познакомились с основами доступа к ресурсам встроенными в Spring средствами. В соответствии с тем, что уроки не предусматривают работу с XML-конфигурациями, а только c Java-конфигурациями, не были рассмотрены варианты указания различных шаблонов в конструктор XML-конфигурациии, но вам ничто не мешает при необходимости ознакомиться с соответствующими разделами документации.

Как указать путь к файлу в java

Чтобы указать путь к файлу в Java , можно использовать класс java.io.File . Существует несколько способов задания пути:

File file = new File("/path/to/file.txt"); // Здесь /path/to/file.txt - абсолютный путь к файлу. 

Относительный путь от текущего каталога:

File file = new File("file.txt"); // Здесь file.txt - файл, расположенный в текущем каталоге. 

Относительный путь от корня проекта:

File file = new File("src/main/resources/file.txt"); 

Чтение ресурсных файлов

Помимо конфигурационных файлов в приложении бывает удобно хранить и некоторые другие файлы ресурсов. Например, тексты или изображения. Достаточно положить эти файлы в папку resources вашего проекта и в процессе выполнения вы сможете получить к ним доступ.

Например, нам нужно прочитать файл test.txt. Положим его в папку resources вашего проекта (она есть и в maven, и в gradle). Важно положить именно в ту resources, которая относится к самому приложению, а не к тестам, иначе вы не сможете обратиться к файлу.

public class ResourceReader <

public static void main(String[] args) throws Exception var example = new ResourceReader();
var content = example.readTextResource( «test.txt» );
System.out.println(content);
>

public String readTextResource(String filename) throws Exception var uri = getClass().getResource(String.format( «/%s» , filename)).toURI();
return Files.readString(Paths.get(uri));
>
>

Доступ к ресурсам мы получаем через метод getResource(), который имеется у объекта Class. Но доступ к классу из статичного контекста метода main() получить нельзя, поэтому мы сначала создаём экземпляр класса, а затем внутри него уже обращаемся к ресурсу. Обратите внимание, что имя ресурса начинается со слеша. Путь до ресурса указывается от корня папки resources. Для чтения содержимого файла целиком в строку используем метод Files.readString(), появившийся в Java 11. Если у вас более ранняя версия Java, то данный метод будет недоступен. В случае, если файл будет очень большим, также лучше данный метод не использовать, а читать файл с помощью буферизованного потока.

То же самое на kotlin:

fun main() <
val example = ResourceReader()
val content = example.readTextResource( «test.txt» )
println(content)
>

class ResourceReader fun readTextResource(filename: String): String val uri = this .javaClass.getResource( «/$filename» ).toURI()
return Files.readString(Paths.get(uri))
>
>

Ожидаемо, что код на kotlin более компактный.

Как получить путь к папке Resource [дубликат]

Как мне указать путь к папке C:\Projects\MyParceXml\Resource У меня такое чувство, что IDEA в упор не видит паку resources. Так и получается Попробовал создать файл:

Path testFile1 = Files.createFile(Paths.get("file1.xml")); 

введите сюда описание изображения

и он появился в паке src: Почему файл создается в папке src? Где это прописывается в IDEA?

Отслеживать
задан 2 авг 2020 в 9:17
349 5 5 серебряных знаков 21 21 бронзовый знак

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Вы не много путаете исходники с скомпилированные кодом. Вы думаете IDEA популярный ide потому что в упор не видит что то? Это не так. Java это не JavaScript когда можно на продакшен нести только исходники и всё будет хорошо.

Вернёмся к вопросу. Java Resources это файла которые будут включены в сборку, а предварительная сборка хранится в target, и во время разработки считайте что они там но явно не привязывайтесь к путям. Надеюсь что ответ помог. Удачи.

По сути если вам нужны ресурсы для тестов то они создаются в тест каталоге по такой же аналогии и доступ к ним такой же как в основном проекте.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *