1.概述

在本文中,我们将介绍使用Spring访问和加载类路径(Classpath)中文件的各种方法。

2. 使用Resource

Spring中的Resource接口有助于抽象化对低级资源的访问。

它支持以统一的方式处理各种文件资源

让我们来看一下获取Resource实例的各种方法。

2.1 手动编码

从类路径(Classpath)访问资源文件,可以简单地使用ClassPathResource

new ClassPathResource("data/text.txt");

默认情况下,使用线程的上下文类加载器来加载资源文件。

但是,我们也可以指定当前的类的类加载器:

new ClassPathResource("data/text.txt", this.getClass().getClassLoader());

或间接通过指定的类:

new ClassPathResource("data/text.txt", XXXX.class.getClassLoader());

我们可以从 Resource轻松跳转到Java标准形式,比如InputStreamFile

需要注意的是,上述方法仅适用于绝对路径。

如果需要要指定相对路径,我们需要传递需要相对的那个类。

new ClassPathResource("../../../data/text.txt", XXXX.class);

上面的文件路径是相对于 XXXX类的。

2.2 使用@Value

我们还可以使用@Value自动注入资源:

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

@Value还支持其他前缀,比如 file: 以及url:

2.3 使用ResourceLoader

如果我们要延迟加载资源,可以使用ResourceLoader,:

@Autowired
ResourceLoader resourceLoader;

然后,我们使用ResourceLoadergetResource方法来获取资源 :

resourceLoader.getResource("classpath:data/text.txt");

对了,ApplicationContext实现了ResourceLoader接口,这意味着我们也可以使用 ApplicationContext来获取资源文件 :

ApplicationContext context;
context.getResource("classpath:data/text.txt");

3. 使用ResourceUtils

Spring还提供了一个资源的工具类ResourceUtils,不过这个类主要是Spring内部使用,我们最好使用

使用Spring的Resource抽象,以统一的方式处理各种文件资源。具体可以去看API doc

ResourceUtils.getFile("classpath:data/text.txt");

4.读取Resource

获得Resource后, 我们可以很方便的读取其内容。

正如我们已经讨论过的,我们可以轻松地从Resource获取FileInputStream对象。

假设我们在类路径上有以下文件data/text.txt

this is test  text file

4.1 通过文件读取

我们可以通过调用getFile读取其内容;

@Test
public void test_resourceReadByGetFile()
  throws IOException {
  File resource = new ClassPathResource("data/text.txt").getFile();
  String text = new String(Files.readAllBytes(resource.toPath()));
  assertEquals("this is test  text file", text);
}

这种方式需要资源存在于文件系统中而不是jar文件中。

4.2 通过输入流读取

如果资源位于Jar文件中,我们可以通过ResourcegetInputStream方法转换成输入流在进行读取。

@Test
public void test_resourceReadByGetInputStream()
  throws IOException {
  InputStream resource = new ClassPathResource("data/text.txt").getInputStream();
  try ( BufferedReader reader = new BufferedReader(
    new InputStreamReader(resource)) ) {
    String text = reader.lines().collect(Collectors.joining("\n"));
    assertEquals("this is test  text file", text);
  }
}

5. 总结

在本文中,我们介绍了使用Spring从类路径访问和读取资源的几种方法,包括即时和延迟加载以及在文件系统或jar中。

最后,和往常一样,代码可以在Github上找到。