关于SpringBoot使用this.class.getResource()获取文件时遇(cu)到(xin)的(da)坑(yi),这里记录一下。
在使用Springboot开发本博客系统时,在resource目录下增加了一些配置文件,代码中需要读取这些文件,故使用了this.getClass().getResource()
获取这些文件。
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包就会找不到文件呢?后面仔细查看具体的报错信息:
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")
能够正常获取到文件流。
InputStream is = ComController.class.getResourceAsStream("/config/xxx.properties");
同理 this.getClass().getClassLoader().getResourceAsStream("config/xxx.properties")
也能够获取到文件流。
注意这两种方式获取流时传入的参数,一个以 "/"
开头,一个不是以 "/"
,具体的区别请查阅我的另一篇博客 关于获取资源文件,Class.getResource 和 ClassLoader.getResource 的区别。