1.问题描述

在项目中,我们经常会遇到在某个包下写一个 配置文件,例如 jdbc.properties 文件;
因为配置文件通常都是在项目中的,因此,我们在编码的时候就需要使用到文件的相对路径
相对路径到底该如何理解呢?
本文将对此概念进行详细的描述。

2.相对路径的理解

相对路径 : 通俗的理解,我们在一个java文件中想要拿到一个文件的路径,
最简单参考点就是src 目录,因为,不管在普通的java项目中还是在maven项目中,
src目录都是一个顶级目录的存在。
因此,一旦提到相对路径,那我们就以src为参考点即可。

3.获取文件相对路径的两种解决方案

3.0 目录及文件准备

下面的这个目录结构很关键,各位corder务必读清楚后再继续往后面读

ProjectName
	| -- src
		| -- aa.properties : 直接在src下面的配置文件
		| -- config
			| -- jdbc-mysql.properties : 在一个配置目录下的配置文件
		| -- com.northcastle.file
			| -- bb.properties : 在一个包中的配置文件
			| -- ApplicationFilePath.java : 一个普通的java类,测试读取不同位置的配置文件

aa.properties 内容如下:
parama=aaa

bb.properties 内容如下:
paramb=bbb

jdbc-mysql.properties 内容如下:
url=jdbc://mysql:3306/xxx
user=root
pwd=aadss

3.1 Classloader的方式

ClassLoader.getResourceAsStream(filePath)  
【可以读取src下的任意级目录的文件】
【既然是相对于src目录,则要求读取的java类也需要在src目录下】

案例代码如下:

// 注意这里的包路径与我们上面描述的项目结构一致
package com.northcastle.file;

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

/**
 * author : northcastle
 * createTime:2022/1/10
 * 本案例进行探究一下java中的使用 ClassLoader+文件相对路径 读取文件
 */
public class ApplicationFilePath {
    public static void main(String[] args) throws IOException {

        /**
         * 1.ClassLoader.getResourceAsStream(filePath)
         *   【可以读取src下的任意级目录的文件】
       	 *   【当前类的包也需要在src目录下】
         */

        //1.准备三个文件再项目中的相对路径 : 相对于 src 的路径
        String path01 = "aa.properties"; // 直接在src下
        String path02 = "com/northcastle/file/bb.properties"; // 在某个包下
        String path03 = "config/jdbc-mysql.properties"; // 在某个包下
        
        //2.准备一个 ClassLoader 对象 : 通过当前类获取即可
        ClassLoader classLoader = ApplicationFilePath.class.getClassLoader();
        
        //3.下面分别读取三个配置文件的内容
        System.out.println("========ClassLoader 读取 aa.properties 开始==============");
        InputStream is01_01 = classLoader.getResourceAsStream(path01);
        Properties properties01_01 = new Properties();
        properties01_01.load(is01_01);
        properties01_01.list(System.out);
        System.out.println("========ClassLoader 读取 aa.properties 结束==============");
        System.out.println();

        System.out.println("========ClassLoader 读取 bb.properties 开始==============");
        InputStream is01_02 = classLoader.getResourceAsStream(path02);
        Properties properties01_02 = new Properties();
        properties01_02.load(is01_02);
        properties01_02.list(System.out);
        System.out.println("========ClassLoader 读取 bb.properties 结束==============");
        System.out.println();

        System.out.println("========ClassLoader 读取 jdbc-mysql.properties 开始==============");
        InputStream is01_03 = classLoader.getResourceAsStream(path03);
        Properties properties01_03 = new Properties();
        properties01_03.load(is01_03);
        properties01_03.list(System.out);
        System.out.println("========ClassLoader 读取 jdbc-mysql.properties 结束==============");
        System.out.println();

    }
}

运行结果如下:

Java 包外相对路径 java中的相对路径_Properties

3.2 Class的方式

class.getResourceAsStream(filePath)
【其实与 ClassLoader.getResourceAsStream(filePath)一致,
【不过需要确保path的前面必须要有一个"/"】
【特例 : 如果被读取的文件与当前类在同一个包下,则可以只写文件名即可!
     (这一点与ClassLoader是不同的;ClassLoader 只写文件名的时候,是该配置文件在src目录下)
】

案例代码:

package com.northcastle.file;

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

/**
 * author : northcastle
 * createTime:2022/1/10
 * 本案例进行探究一下 java中的文件路径的问题
 */
public class ApplicationFilePath {
    public static void main(String[] args) throws IOException {

        /**
         * 2.class.getResourceAsStream(filePath)
         *    【其实与 ClassLoader.getResourceAsStream(filePath)一致,
         *     不过需要确保path的前面必须要有一个"/"】
         */

        //1.准备三个文件再项目中的相对路径 : 相对于 src 的路径
        //   注意 : 此时,每个相对路径的前面必须以 “/” 开始!!!
        String path01 = "/aa.properties"; // 直接在src下
        String path02 = "/com/northcastle/file/bb.properties"; // 在某个包下
        String path03 = "/config/jdbc-mysql.properties"; // 在某个包下
        String path04 = "bb.properties"; // 同包下的一个文件

        //2.准备一个Class对象 : 直接使用当前类即可
        Class<ApplicationFilePath> applicationFilePathClass = ApplicationFilePath.class;

        //3.下面进行文件的读取操作
        System.out.println("========Class.getResourceAsStream 读取 aa.properties 开始==============");
        InputStream is02_01 = applicationFilePathClass.getResourceAsStream(path01);
        Properties properties02_01 = new Properties();
        properties02_01.load(is02_01);
        properties02_01.list(System.out);
        System.out.println("========Class.getResourceAsStream 读取 aa.properties 结束==============");
        System.out.println();
        
        System.out.println("========Class.getResourceAsStream 读取 bb.properties 开始==============");
        InputStream is02_02 = applicationFilePathClass.getResourceAsStream(path02);
        Properties properties02_02 = new Properties();
        properties02_02.load(is02_02);
        properties02_02.list(System.out);
        System.out.println("========Class.getResourceAsStream 读取 bb.properties 结束==============");
        System.out.println();
        
        System.out.println("========Class.getResourceAsStream 读取 jdbc-mysql.properties 开始==============");
        InputStream is02_03 = applicationFilePathClass.getResourceAsStream(path03);
        Properties properties02_03 = new Properties();
        properties02_03.load(is02_03);
        properties02_03.list(System.out);
        System.out.println("========Class.getResourceAsStream 读取 jdbc-mysql.properties 结束==============");
        System.out.println();

  		System.out.println("========Class.getResourceAsStream 读取 bb.properties 开始==============");
        InputStream is02_04 = applicationFilePathClass.getResourceAsStream(path04);
        Properties properties02_04 = new Properties();
        properties02_04.load(is02_04);
        properties02_04.list(System.out);
        System.out.println("========Class.getResourceAsStream 读取 bb.properties 结束==============");
        System.out.println();
    }

}

运行结果如下:

Java 包外相对路径 java中的相对路径_Java 包外相对路径_02

3.完成

Congratulations!
You are one step closer to success!