文章目录
1. 前提说明
- 一般写代码读取io文件的时候,路径可以写相对路径以及绝对路径,在开发环境下,没有什么所谓。
- 但部署项目的时候,路径选择使用绝对路径是更加优的选择。
- 比如打包项目,会将项目打包成Jar包或者war包,此时就不会存在 src/main/resources 目录,JVM会在编译项目时,主动将 java文件编译成 class文件 和 resources 下的静态文件放在 target/classes目录下。
- 那么将如何获取在Resource下的资源文件呢。
2. 获取Resource下资源文件的方法
- ClassPathResource方法。
- 使用getResourceStream方法,本质使用类加载器classloader,分别为this.class.getResourceStream 与 this.class.getClassloader.getResourceStream。
3. ClassPathResource使用
-
ClassPathResource 默认是读取Resource(classpath)下的文件。
-
先创建一个文件,如下图:
-
代码
public class ClassPathResource_Test { public static void main(String[] args) { // ClassPathResource 读取文件 ClassPathResource classPathResource = new ClassPathResource("ReadResourceFile.txt"); // 获取输入流 try (InputStream inputStream = classPathResource.getInputStream()) { int len; byte[] buffer = new byte[1024]; while ((len = inputStream.read(buffer)) != -1) { System.out.println(new String(buffer, 0, len)); } } catch (IOException e) { e.printStackTrace(); } } }
结果: 我是在resources的文件
3. 使用getResourceStream获取,本质是类加载器classloader
0. 前提须知,如何将src/main/java下的资源进行打包到target中
- 因为Class.getResourceAsStream中变量path 不以’/'开头时默认是从此类所在的包下取资源,而springboot项目默认不打包src下除了.java的其他文件,为了测试下面,因此我们需要设置,让其允许其他资源打包。
- https://blog.csdn.net/xueyijin/article/details/121441448
1. this.class.getResourceStream
-
Class.getResourceAsStream(String path) :
- path 不以’/'开头时默认是从此类所在的包下取资源,
- 以’/'开头则是从 ClassPath根下获取。
- 最终还是由ClassLoader获取资源。
-
代码
准备两个文件,一个在类所在包下,一个在resource资源下。
不加 / 的情况:public class Class_getResourceAsStream { public static void main(String[] args) { // 不加 / 是从当前类所在包下获取资源 try (InputStream in = Class_getResourceAsStream.class.getResourceAsStream("ReadResourceFile.txt")) { // 加 / 是从classPath下加载资源 // InputStream in = Class_getResourceAsStream.class.getResourceAsStream("/ReadResourceFile.txt") byte[] bytes = new byte[1024]; int len; while ((len = in.read(bytes)) != -1) { System.out.println(new String(bytes, 0, len)); } } catch (IOException e) { e.printStackTrace(); } } }
加 / 的情况:
2. 为什么this.class.getResourceStream也是使用类加载器
根据源码所示:
// 在Class类中
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
// 这里调用了getClassLoader0
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
// 可得其实在Class类中,有个成员变量是保存classLoader
ClassLoader getClassLoader0() {
return classLoader;
}
3. this.class.getClassloader.getResourceStream
-
Class.getClassLoader.getResourceAsStream(String path) : 默认则是从ClassPath根下获取,path不能以’/'开头,最终是由 ClassLoader获取资源。
-
代码:
public class Classloader_getResourceStream_Test { public static void main(String[] args) { try (InputStream in = Class_getResourceAsStream.class.getClassLoader().getResourceAsStream("ReadResourceFile.txt")) { byte[] bytes = new byte[1024]; int len; while ((len = in.read(bytes)) != -1) { System.out.println(new String(bytes, 0, len)); } } catch (IOException e) { e.printStackTrace(); } } }