读取resources资源-class.getResource、ClassLoader.getResource和getResourceAsStream的区别
- 我们一般把配置,环境配置,或者数据库的驱动,以及properties等配置放到resources目录下,有时候我们需要获取这里面的配置文件,则需要使用getResource、ClassLoader.getResource和getResourceAsStream()等方法去读取
classpath
读取资源文件,即要找到文件的位置,即找路径。路径和classpath有很大的关系。
.java文件都是.java文件,要运行的话,要编译成.class文件才会被jvm运行。jvm要运行.class,就得找到对应的classpath。
- jvm编译项目的时,主的java和静态的。会把编译后的.class文件和resources目录下的静态文件放在一起。放到target/classes下面
- 测试java会放在/target/test-classes.
package test_demo;
import org.junit.Test;
public class ResourceTest {
@Test
public void test(){
System.out.println(ResourceTest.class.getResource(""));
// 不写是空的话,是从当前类,所在的包路径去获取资源,即当前类是ResourceTest所在的包路径是test_demo去获取资源,
// file:/D:/java_study/code_stay/mybatis/demo02/target/test-classes/test_demo/
System.out.println(ResourceTest.class.getResource("/"));
// 带/是获取test-classes的路径
// file:/D:/java_study/code_stay/mybatis/demo02/target/test-classes/
System.out.println(ResourceTest.class.getResource("3.txt")); // null
System.out.println(ResourceTest.class.getResource("test/2.txt")); // null
// 这里不带/,获取的都是null,因为不带/,所以是从当前类ResourceTest所在的test_demo包的路径去找,这个里面是没有3.txt和2.txt的资源的。
/*
getResource("")不带/的时候是从当前类,所在的包路径去获取资源
带"/"的时候是从classpath的根路径去获取
*/
System.out.println(ResourceTest.class.getResource("/3.txt"));
// 写了/具体,就从classes里面找,因为这个是静态的,所以从classes里面找
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/3.txt
System.out.println(ResourceTest.class.getResource("/test/2.txt"));
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/test/2.txt
}
}
getClassLoader().getResource()
@Test
public void test2(){
System.out.println(ResourceTest.class.getClassLoader().getResource(""));
// file:/D:/java_study/code_stay/mybatis/demo02/target/test-classes/
// 1、 getClassLoader().getResource("")不带"/"时候是从classpath的根路径获取,又因为没写具体的,所以打印出来的是从测试里面找的。如果有具体的,就是从clasespath根目录找
System.out.println(ResourceTest.class.getClassLoader().getResource("/"));
// null
System.out.println(ResourceTest.class.getClassLoader().getResource("3.txt"));
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/3.txt
System.out.println(ResourceTest.class.getClassLoader().getResource("test/2.txt"));
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/test/2.txt
}
- getResourceAsStream() 方法仅仅是获取对应路径文件的输入流,在路径的用法上与getResource()一致
总结
- class.getResource()和class.getClassLoder().getResource()两者通过一个少一个方法,要获取classpath的根路径就得多一个"/",多一个方法要获取就得少一个“/”
- class.getResource()不带"/"时候是从当前类所在包路径去获取资源
- class.getResource()带"/"时候是从classpath的根路径获取
- getClassLoader().getResource("")不带"/"时候是从classpath的根路径获取
- getClassLoader().getResource("/")路径中无法带有"/"
- getResourceAsStream() 方法仅仅是获取对应路径文件的输入流,在路径的用法上与getResource()一致
- Resources和具体的类ResourceTest.class所获取的路径是一样的
System.out.println(Resources.getResourceURL("3.txt"));
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/3.txt
System.out.println(ResourceTest.class.getClassLoader().getResource("3.txt"));
// file:/D:/java_study/code_stay/mybatis/demo02/target/classes/3.txt