假设有个代码目录结构为

java
├── hello
│   └── world
│       ├── Test.java
│       └── hello.txt
└── hello1.txt

则可以这样子读取 hello.txthello1.txt 的资源

class 方式

package hello.world;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) throws IOException {
        final InputStream v = Test.class.getResourceAsStream("/hello/world/hello.txt");
        if (v == null) {
            System.out.println("null");
            return;
        }
        System.out.println("has data=>");
        try (BufferedReader buffer = new BufferedReader(new InputStreamReader(v))) {
            System.out.println(buffer.lines().collect(Collectors.joining("\n")));
        }
    }
}

v 为 null 时, 表示不存在该资源.

  • 绝对路径写法: /hello/world/hello.txt
  • 相对路径写法: hello.txt 表示相对于 Test.class 所在的包下的路径. 这里即为相对于 /hello/world/ 的路径.

跨 jar 文件也可以这样子读取. 只要是同一个 classLoader 中加载的话. 所以的资源都可以 / 开头的形式的绝对路径写法来定位.

classLoader 方式

注意, classLoader 方式只能使用绝对路径, 并且, 它的绝对路径不是以 / 开头的. 即:

final InputStream v = Test.class.getResourceAsStream("/hello/world/hello.txt");

=>

final InputStream v = Test.class.getClassLoader().getResourceAsStream("hello/world/hello.txt");