关于SpringBoot使用this.class.getResource()获取文件时遇到的坑

关于SpringBoot使用this.class.getResource()获取文件时遇(cu)到(xin)的(da)坑(yi),这里记录一下。

在使用Springboot开发本博客系统时,在resource目录下增加了一些配置文件,代码中需要读取这些文件,故使用了this.getClass().getResource()获取这些文件。

1
2
String path = this.class.getResource("/config/xxx.properties").getPath();
FileInputStream fis = new FileInputStream(new File(path));

在IDE工具中开发及Debug时一切都正常,但是打成Jar包发布到线上时就会出现java.io.FileNotFoundException

报错很直白的告诉我们是因为文件不存在,仔细检查了文件及代码,而且也确认在IDE工具中一切正常,而且也将打成的Jar包解压确认文件确实打包进去了。

那么为什么会导致打成Jar包就会找不到文件呢?后面仔细查看具体的报错信息:

1
java.io.FileNotFoundException: file:\E:\repo\guitu-blog\target\guitu-blog-1.0.0-SNAPSHOT.jar!\BOOT-INF\classes!\config\xxx.properties

检查路径发现在磁盘确实不存在这样一条路径,因为路径从 ...\guitu-blog-1.0.0-SNAPSHOT.jar\...开始,后面的文件路径都是打到Jar包中的,磁盘没有后面 ...\BOOT-INF\classes!\config\xxx\xxx.properties这样的目录;

在Jar包中的文件在磁盘是没有实际路径的,所以通过这时候可以通过 this.getClass().getResource() 无法获取文件。
此时可以通过 this.getClass().getResourceAsStream("/config/xxx.properties") 能够正常获取到文件流。

1
InputStream is = ComController.class.getResourceAsStream("/config/xxx.properties");

同理 this.getClass().getClassLoader().getResourceAsStream("config/xxx.properties") 也能够获取到文件流。

注意这两种方式获取流时传入的参数,一个以 "/" 开头,一个不是以 "/" ,具体的区别请查阅我的另一篇博客 关于获取资源文件,Class.getResource 和 ClassLoader.getResource 的区别

明人不说暗话,如果你觉得可以的话,你懂的!