对各种读取资源文件的情况做了一下总结:

1. 场景说明

  • 当前项目中,各个properties文件和java文件的相对位置,结构如下图所示:
  • 在依赖的第三方jar包中,文件结构如下所示:

2. 代码

TestPath.java中读取取各个properties文件,主要采用以下两种方式:

方式一:Class.getResourceAsStream(path)  
复制代码

方式二:Class.getClassLoader().getResourceAsStream(path) 
复制代码

具体的测试代码如下:

/** 
 * Class.getResourceAsStream 
 *  
 * @param path 
 *            各个文件的路径 
 */  
public static void getResourceAsStream(String path) {  
    InputStream input = TestPath.class.getResourceAsStream(path);  
    showPath(input);  
}  
  
/** 
 * Class.ClassLoader.getResourceAsStream 
 *  
 * @param path 
 *            各个文件的路径 
 */  
public static void classLoadGetResourceAsStream(String path){  
    InputStream input = TestPath.class.getClassLoader().getResourceAsStream(path);  
    showPath(input);  
}  
  
/** 
 * print content in per file 
 * @param input 
 */  
public static void showPath(InputStream input) {  
    Properties prop = new Properties();  
  
    if (null == input) {  
        throw new RuntimeException("can not load properties: " + input);  
    }  
  
    try {  
        prop.load(input);  
        input.close();  
        for (Entry<Object, Object> entry : prop.entrySet()) {  
            System.out.println(entry.getKey().toString() + "="  
                    + entry.getValue().toString());  
        }  
  
    } catch (IOException e) {  
        throw new RuntimeException("can not read properties: " + input);  
    }  
}  
复制代码

3. 方式一

  • 测试代码
public static void testGetResourceAsStream() {  
    System.out.println("文件与当前class在同一目录");  
    getResourceAsStream("current_path.properties");  
    getResourceAsStream("/com/java/path/test/current_path.properties");  
  
    System.out.println("文件在当前class上级目录");  
    getResourceAsStream("../parent_path.properties");  
    getResourceAsStream("/com/java/path/parent_path.properties");  
  
    System.out.println("文件与当前class在不同的package");  
    getResourceAsStream("/com/java/pathanother/another_package.properties");  
  
    System.out.println("文件在class根目录");  
    getResourceAsStream("/root_path.properties");  
      
    System.out.println("文件位于的依赖第三方包");  
    getResourceAsStream("/META-INF/maven/commons-logging/commons-logging/pom.properties");  
}  
复制代码
  • 输出
文件与当前class在同一目录  
path=com.java.path.test  
path=com.java.path.test  
  
文件在当前class上级目录  
path=com.java.path  
path=com.java.path  
  
文件与当前class在不同的package  
path=com.java.pathanother  
  
文件在class根目录  
path=root  
  
文件位于的依赖第三方包  
version=1.1.1  
groupId=commons-logging  
artifactId=commons-logging
复制代码

4. 方式二

  • 测试代码
public static void testClassLoadGetResourceAsStream() {  
    System.out.println("文件与当前class在同一目录");  
    classLoadGetResourceAsStream("com/java/path/test/current_path.properties");  
  
    System.out.println("文件在当前class上级目录");  
    classLoadGetResourceAsStream("com/java/path/parent_path.properties");  
  
    System.out.println("文件与当前class在不同的package");  
    classLoadGetResourceAsStream("com/java/pathanother/another_package.properties");  
  
    System.out.println("文件在class根目录");  
    classLoadGetResourceAsStream("root_path.properties");  
      
    System.out.println("文件位于的依赖第三方包");  
    classLoadGetResourceAsStream("META-INF/maven/commons-logging/commons-logging/pom.properties");  
}  
复制代码
  • 输出
文件与当前class在同一目录  
path=com.java.path.test  
  
文件在当前class上级目录  
path=com.java.path  
  
文件与当前class在不同的package  
path=com.java.pathanother  
  
文件在class根目录  
path=root  
  
文件位于的依赖第三方包  
version=1.1.1  
groupId=commons-logging  
artifactId=commons-logging 
复制代码

5. 总结

  1. Test.class.getResource()中资源可以写成绝对路径和相对路径
  2. 如果Test.class.getResource()资源是以/开头,则指向CLASSPATH根目录
  3. 如果Test.class.getResource()资源是以文件(包名)开头,则相对Test.class文件所在的包查找资源
  4. Test.class.getClassLoader().getResource()资源 只能写成相对路径,以文件(包名)开头(注:getClassLoader().getResource("/")是错误的),是以CLASSPATH为根目录查找资源,相当于class.getResource()中写绝对路径。

6. 注意



  • src/main/java
    中的java文件
    只能直接加载src/main/resources下的资源,不能直接加载src/test/resources下的资源;
  • src/test/java
    中的java文件
    既能加载src/test/resources下的资源,又能加载src/main/resources下的资源
    当两个resources下都有要加载的同名资源时候,优先选择src/test/java下的资源;