文章目录

  • 前言
  • 1.类加载器获取的两种方式
  • 1.1 A.class.getResource("/message.properties")
  • 1.2 A.class.getClassLoader().getResource("message.properties")
  • 分析
  • 总结:
  • 2. 简单的ResourceBundle 读取
  • 3.绝对路径直接获取


前言

在开发项目中经常获取resources下的文件(配置文件及其他各种各样的文件),本文通过java代码在idea环境获取maven工程下的文件及输入流;

如图,我要获取maven项目的resources下的message.properties文件里面的内容

java 获取maven项目根路径 maven获取resource路径_java 获取maven项目根路径

java 获取maven项目根路径 maven获取resource路径_System_02

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"));
        //输出结果为中国
    }

另外,这里还有一个获取当前项目路径的方法

java 获取maven项目根路径 maven获取resource路径_加载_03

@Test
    public void test6(){
        System.out.println(System.getProperty("user.dir"));
        //输出为  E:\IdeaPro\apple_test
    }