码上游记

hongjian.xia的个人博客

0%

Spring Boot项目打包成jar部署读取Resources下的文件

起源

Spring Boot项目打包成jar部署时,发现平时使用读取Resources目录的文件报错了,无法正确读取到文件。

原因分析

项目结构

src
  |--main
      |--java
      |    |--com
      |        |--example
      |              |-- ...  
      |--resouces
          |--data
              |--data.json

现在需要做的事读取data.json中的内容,下面是我实现的代码

1
2
3
class InitData {
return Files.readAllBytes(Paths.get(ResourceUtils.getFile("classpath:data/data.json").getAbsolutePath()));
}

由于项目是打包成jar部署的,所以getAbsolutePath()返回的是jar:开头的路径,即使用的的jar协议。而查看Path#get方法源码,使用的FileSystem只支持file协议,因此是无法正确获取到文件并读取数据。同样获取到File对象,创建FileInputStream读取文件也是不行的,因为FileInputStream也不支持jar协议。

解决

1
2
3
4
5
6
7
8
9
10
public class InitData {
public static byte[] getData() throws IOException {
InputStream in = ResourceUtils.getURL("classpath:data/data.json").openStream();
// InputStream in = new DefaultResourceLoader().getResource("classpath:data/data.json").getInputStream();
// InputStream in = InitData.class.getResourceAsStream("data/data.json");
// InputStream in = InitData.class.getResource("data/data.json").openStream();
// 使用 InputStream读取文件内容
// ...
}
}

上面几种实现方式大同小异,都是获取到InputStream,然后是用InputStream读取文件内容。

总结

IO操作时需要注意操作资源的协议,某些类库是只支持file协议的,用它们操作其他协议资源则会产生异常。