Перейти к основному содержимому

Доступ к файлу из пути к классам в приложении Spring

· 4 мин. чтения

1. Введение

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

2. Использование ресурса

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

Начнем с рассмотрения различных методов получения экземпляра Resource .

2.1. Вручную

Для доступа к ресурсу из пути к классам мы можем просто использовать ClassPathResource :

public Resource loadEmployeesWithClassPathResource() {
return new ClassPathResource("data/employees.dat");
}

По умолчанию ClassPathResource удаляет некоторые шаблоны, выбирая между загрузчиком классов контекста потока и системным загрузчиком классов по умолчанию.

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

return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());

Или косвенно через указанный класс:

return new ClassPathResource(
"data/employees.dat",
Employee.class.getClassLoader());

Обратите внимание, что из Resource мы можем легко перейти к стандартным представлениям Java, таким как InputStream или File .

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

new ClassPathResource("../../../data/employees.dat", Example.class).getFile();

Приведенный выше путь к файлу относится к классу Example .

2.2. Использование @значения

Мы также можем внедрить Resource с помощью @Value :

@Value("classpath:data/resource-data.txt")
Resource resourceFile;

@Value также поддерживает другие префиксы, такие как file: и url: .

2.3. Использование ResourceLoader

Если мы хотим лениво загружать наш ресурс, мы можем использовать ResourceLoader :

@Autowired
ResourceLoader resourceLoader;

Затем мы получаем наш ресурс с помощью getResource :

public Resource loadEmployeesWithResourceLoader() {
return resourceLoader.getResource(
"classpath:data/employees.dat");
}

Также обратите внимание, что ResourceLoader реализуется всеми конкретными ApplicationContext , а это означает, что мы также можем просто зависеть от ApplicationContext , если это лучше подходит для нашей ситуации:

ApplicationContext context;

public Resource loadEmployeesWithApplicationContext() {
return context.getResource("classpath:data/employees.dat");
}

3. Использование ResourceUtils

В качестве предостережения: в Spring есть еще один способ извлечения ресурсов, но в Javadoc ResourceUtils ясно, что этот класс предназначен в основном для внутреннего использования.

Если мы увидим использование ResourceUtils в нашем коде:

public File loadEmployeesWithSpringInternalClass() 
throws FileNotFoundException {
return ResourceUtils.getFile(
"classpath:data/employees.dat");
}

Мы должны внимательно рассмотреть обоснование, так как , вероятно, лучше использовать один из стандартных подходов, описанных выше .

4. Чтение данных о ресурсах

Когда у нас есть ресурс, нам легко читать его содержимое. Как мы уже говорили, мы можем легко получить ссылку на File или InputStream из Resource .

Давайте представим, что у нас есть следующий файл data/employees.dat в пути к классам :

Joe Employee,Jan Employee,James T. Employee

4.1. Чтение как файл

Теперь мы можем прочитать его содержимое, вызвав getFile:

@Test
public void whenResourceAsFile_thenReadSuccessful()
throws IOException {

File resource = new ClassPathResource(
"data/employees.dat").getFile();
String employees = new String(
Files.readAllBytes(resource.toPath()));
assertEquals(
"Joe Employee,Jan Employee,James T. Employee",
employees);
}

Хотя следует отметить, что этот подход предполагает, что ресурс будет присутствовать в файловой системе, а не в файле jar.

4.2. Чтение как InputStream

Допустим, однако, что наш ресурс находится внутри банки.

Тогда мы можем вместо этого прочитать Resource как InputStream :

@Test
public void whenResourceAsStream_thenReadSuccessful()
throws IOException {
InputStream resource = new ClassPathResource(
"data/employees.dat").getInputStream();
try ( BufferedReader reader = new BufferedReader(
new InputStreamReader(resource)) ) {
String employees = reader.lines()
.collect(Collectors.joining("\n"));

assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
}
}

5. Вывод

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

Как всегда, все эти примеры доступны на GitHub .