文章目录
前言
在开发项目中经常获取resources下的文件(配置文件及其他各种各样的文件),本文通过java代码在idea环境获取maven工程下的文件及输入流;
如图,我要获取maven项目的resources下的message.properties文件里面的内容
1.类加载器获取的两种方式
这里先给一个结论:
A.class.getResource("/") == A.class.getClassLoader().getResource("")
注意:后者路径里面是没有/的
1.1 A.class.getResource("/message.properties")
@Test
public void test1() throws IOException {
URL resource = PathDemo2.class.getResource("/message.properties");
InputStream inputStream=new FileInputStream(resource.getPath());
Properties properties=new Properties();
properties.load(inputStream);
System.out.println(properties.getProperty("name"));
//输出结果为中国
}
1.2 A.class.getClassLoader().getResource(“message.properties”)
@Test
public void test2() throws IOException {
URL resource =PathDemo2.class.getClassLoader().getResource("message.properties");
InputStream inputStream=new FileInputStream(resource.getPath());
Properties properties=new Properties();
properties.load(inputStream);
System.out.println(properties.getProperty("name"));
//输出结果为中国
}
注意这里面可以直接使用getResourceAsStream获取文件的输入流:
URL resource = PathDemo2.class.getResource("/message.properties");
InputStream inputStream=new FileInputStream(resource.getPath());
//也等价于
InputStream inputStream=PathDemo2.class.getResourceAsStream("/message.properties")
InputStream inputStream=PathDemo2.class.getClassLoader().getResourceAsStream("message.properties")
这里还要注意的一个点是URL的getPath()和getFile()相等,但是不等于toString,一开始我直接用toString发现报错了!
URL resource = PathDemo2.class.getClassLoader().getResource("message.properties");
System.out.println(resource.getPath().equals(resource.getFile())); //true
System.out.println(resource.getPath().equals(resource.toString())); //false
但是这种情况下是不一样的:
URL url = new URL("file://ftp.yoyodyne.com/pub/files/foobar.txt?id=123456");
System.out.println("url.getFile()="+url.getFile());
System.out.println("url.getPath()="+url.getPath())
url.getFile()=/pub/files/foobar.txt?id=123456
url.getPath()=/pub/files/foobar.txt
分析
Class.getResource(String path)
1.path不以’/'开头时,默认是从此类所在的包下取资源;
2. path 以’/'开头时,则是从ClassPath根下获取;
Class.getResource和Class.getResourceAsStream在使用时,路径选择上是一样的!!!
- 上面说到的【path以’/'开头时,则是从ClassPath根下获取;】在这里就是相当于bin目录(Eclipse环境下)。
- 上面说到的【path以’/'开头时,则是从ClassPath根下获取;】在这里就是相当于target目录(Idea环境下)。
Class.getClassLoader().getResource(String path)
path不能以’/'开头,path是从ClassPath根下获取;
总结:
1.其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。
2.Class.getResource真正调用ClassLoader.getResource方法之前,会先获取文件的路径(path不以’/‘开头时,默认是从此类所在的包下取资源;path以’/'开头时,则是从项目的ClassPath根下获取资源)。
3.ClassLoader.getResource方法会通过双亲委派机制,先委派双亲去加载类,如果双亲没有加载到,则再由自己加载。
2. 简单的ResourceBundle 读取
这里直接获取路径,不用带/,并且也不要加上.properties,加上反而会报错
@Test
public void test3(){
ResourceBundle res = ResourceBundle.getBundle("message");
System.out.println(res.getString("name"));
//输出结果为中国
}
3.绝对路径直接获取
也可以使用绝对路径直接获取,但是这个不太推荐,因为换一台机器路径就变了,不灵活!
@Test
public void test5() throws IOException {
InputStream inputStream=new FileInputStream("E:\\IdeaPro\\apple_test\\src\\main\\resources\\message" +
".properties");
Properties properties=new Properties();
properties.load(inputStream);
System.out.println(properties.getProperty("name"));
//输出结果为中国
}
另外,这里还有一个获取当前项目路径的方法
@Test
public void test6(){
System.out.println(System.getProperty("user.dir"));
//输出为 E:\IdeaPro\apple_test
}