Java读取配置文件,xxx.class.getClassLoader().getResourceAsStream("");和xxx.class.getResourceAsStream("");的区别

一、需求说明:

  有时候我们做项目,会遇到一个问题,就是我们在开发时候代码里面有很多路径到了部署的时候这些路径全部都要修改,有时候路径一多,自己难免也会忘记,本来代码就写了半天,结果到了部署的时候又要修改源码然后重新编译打包部署,像这样操作,实在是麻烦,而且路径一多,可能到修改的时候根本就改不彻底,浪费大量时间。因此就有了一种很好的解决方案,就是把项目里面的一些路径和url都写到配置文件里面,部署的时候就不用去修改源代码了,直接修改配置文件,而且所有的路径和url都在一个配置文件里面方便查找也不会遗漏,这样极大的方便了我们的部署。

二、先要了解的事

  用eclipse新建一个项目之后,会自动生成一些目录,如下图所示:

java File加载resources下的文件 java读取resource文件_配置文件


  其中src下面是我们自己编写的代码,bin目录下面是编译后的代码,就是src下面写的代码,eclipse会在我们保存代码之后自动编译成字节码文件然后发到bin目录下,这些都是eclipse帮忙干的。

三、编写一个配置文件

  了解了这些之后,接下来看怎么实现编写一个代码读取配置文件。

3.1 发现问题

1、由于项目需要,我弄了多个配置文件,为了方便管理,我先在src下面创建了一个配置文件目录config,然后再config下又创建一个constant.properties,initconfig.properties等三个配置文件,如下图所示:

java File加载resources下的文件 java读取resource文件_java的ClassLoader类加载器_02


2、这里我以读取constant.properties配置文件为例,编写java代码,其他的配置文件读取方法一样。

首先看constant.properties中的内容:

server_ip=localhost:8080	#读取服务器的IP地址

然后我像往常一样编写了如下java代码:

package top.jacktgq.utils;

import java.io.InputStream;
import java.util.Properties;

/**
 * @Author CandyWall
 * @Date 2019/8/15--15:11
 * @Description 读取配置文件中的常数
 */
public class ConstantUtils {
    private static Properties pro;

    static {
        try {
            initProperties();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String getServer_ip() {
        return pro.getProperty("server_ip");
    }

    private static synchronized void makeInstance() {
        if (pro == null) {
            pro = new Properties();
        }
    }

    private static void initProperties() throws Exception {
        InputStream in = ConstantUtils.class.getClassLoader().getResourceAsStream("/config/constant.properties");
        if (pro == null) {
            makeInstance();
        }
        pro.load(in);
    }
}

测试类代码如下:

package top.jacktgq.test;

import top.jacktgq.utils.ConstantUtils;

/**
 * 
* @Title: ConstantUtilsDemo.java 
* @Package top.jacktgq.test 
* @Description: 读取配置文件测试
* @author CandyWall   
* @date 2019年11月17日 上午10:22:22 
* @version V1.0
 */
public class ConstantUtilsDemo {
	public static void main(String[] args) {
		System.out.println("server_ip:" + ConstantUtils.getServer_ip());
	}
}

还以为直接就能搞定,没想到报了如下错误:

java File加载resources下的文件 java读取resource文件_java的ClassLoader类加载器_03

3.2 解决问题:

百思不得其解的时候,我去回看了一下我以前编写过的类似的读取配置文件的例子,点击运行没报错,能读取到配置文件中的内容。啊哈,太奇怪了吧,经过对比,我发现我之前的例子里面,配置文件是直接放在了src的根目录下面,代码经过eclipse编译过后是直接放在bin的根目录下,我抱着试一试的心态,然后把constant.properties文件放到了src的根目录下,如下图所示:

java File加载resources下的文件 java读取resource文件_getResourceAsStream_04


然后调整代码中的配置文件的访问的url:

java File加载resources下的文件 java读取resource文件_Java读取配置文件_05


然后再运行测试类,能够运行成功:

java File加载resources下的文件 java读取resource文件_配置文件_06

3.3 更多的问题

  由此引发了我的疑惑,我就想把放到config下面难道不行吗?

经过测试,我找到了解决方法:

1、将constant.properties配置文件移回config目录下:

java File加载resources下的文件 java读取resource文件_Java读取配置文件_07


2、修改ConstantUtils.java代码,修改url为/config/constant.properties,并去掉getClassLoader(),如下图所示:

java File加载resources下的文件 java读取resource文件_Properties类_08


修改后:

java File加载resources下的文件 java读取resource文件_Properties类_09


运行结果如下,能读取成功。

java File加载resources下的文件 java读取resource文件_java的ClassLoader类加载器_10

3.4、问题的总结:

xxx.class.getClassLoader().getResourceAsStream(“constant.properties”);和xxx.class.getResourceAsStream("/config/constant.properties");都能读取到配置文件。不同的是,
  xxx.class.getClassLoader().getResourceAsStream(“constant.properties”);这种读取方式需要把配置文件放到src的根目录下,getClassLoader()会读取bin的根目录,然后寻找constant.properties配置文件,如果没有在根目录下找到,就会报错。
  而xxx.class.getResourceAsStream("/config/constant.properties");这种读取方式就可以更自由一些了,它可以加载bin目录下一些复杂一点的目录下的配置文件,比如/config/constant.properties

这就是本次的所有内容,如果有问题请在评论区留言指正,非常感谢!!!