Spring 应用访问Classpath路径下的文件
本文我们了解下spring多种方式访问classpath路径下文件。
1. 使用Resource
Resource接口是对底层资源的抽象。提供以统一的方式操作各种文件资源。首先我们看获得Resource实例的不同方法。
1.1. 手工获取
可以简单使用ClassPathResource类访问classpath路径下文件:
public Resource loadEmployees() {
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获得InputStream或File等Java标准表示形式。这里需要提醒的另一件事是,上面的方法只适用于绝对路径。如果希望取得相对路径,需传入第二个类参数。路径将相对于这个类:
new ClassPathResource("../../../data/employees.dat", Example.class).getFile();
上面的文件路径是相对于Example类。
1.2. 使用@Value
可以使用@Value注入Resource:
@Value("classpath:data/resource-data.txt")
Resource resourceFile;
@Value也支持其他前缀,如:file和url:
1.3. 使用ResourceLoader
如果想懒价值资源,可以使用ResourceLoader:
@Autowired
ResourceLoader resourceLoader;
然后使用getResource方法获得资源:
public Resource loadEmployees() {
return resourceLoader.getResource("classpath:data/employees.dat");
}
这里也说明下,ResourceLoader是由所有具体的ApplicationContext实现的,这意味着在更适合的场景,也可以简单地通过ApplicationContext获取资源:
ApplicationContext context;
public Resource loadEmployees() {
return context.getResource("classpath:data/employees.dat");
}
2. 使用ResourceUtils
需要注意的是,在Spring中还有另一种检索资源的方法,但是ResourceUtils Javadoc很清楚说明该类主要是内部使用。使用示例代码:
public File loadEmployeesWithSpringInternalClass() throws FileNotFoundException {
return ResourceUtils.getFile("classpath:data/employees.dat");
}
我们应该仔细考虑其实现机理,因为使用上面提及的标准方法可能更好。
3. 读取资源数据
获得Resource之后,读取内容也就比较容易了。之前也提及了,通过Resource可以很方便获得File或InputStream。假设classpath有data/employee.data文件,内容如下:
Joe Employee,Jan Employee,James T. Employee
3.1. 获得File
通过getFile方法或的File:
@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文件中。
3.2. 获取InputStream
如果资源是在jar中,那么需要使用Resource的getInputStream方法:
@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);
}
}
4. 总结
本文我们介绍了Spring提供的几种方法访问和读取classpath路径下的文件,可以是立刻加载和懒价值,包括文件系统文件或jar中的文件。