从Jar包中读取配置文件

项目目录结构如下:

若想读取application.yml配置,可使用以下方式:

常规使用

如在 IDE 中运行

绝对路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 使用绝对路径获取
*
* @throws IOException
* @author Forest Dong
* @date 2024/03/19 11:39
*/
public void getResource1() throws IOException {
File file = new File("/Users/forest/Work/IdeaProjects/study/java-study/src/main/resources/application.yml");
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String s = "";
while ((s = br.readLine()) != null)
System.out.println(s);
}
}

相对路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 使用相对路径获取
*
* @throws IOException
* @author Forest Dong
* @date 2024/03/19 11:39
*/
public void getResource2() throws IOException {
File file = new File("src/main/resources/application.yml");
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String s = "";
while ((s = br.readLine()) != null)
System.out.println(s);
}
}

以上代码在 IDE 中可正常运行,但当我们打成 Jar包后运行会报找不到文件。

这主要是因为jar包是一个单独的文件而非文件夹,不能通过绝对路径获取,即使是相对路径,也无法定位到jar文件内的文件。

Jar包中读取

可以使用类加载器(ClassLoader)实现:

(1) ClassLoader 是类加载器的抽象类。它可以在运行时动态的获取加载类的运行信息。

  • public URL getResource(String name) 查找具有给定名称的资源。资源是可以通过类代码以与代码无关的方式访问的一些数据(图像、声音、文本等)。并返回资源的URL对象。
  • public InputStream getResourceAsStream(String name); 返回读取指定资源的输入流。这个方法很重要,可以直接获得jar包中文件的内容。

(2) ClassLoader是abstract的,不可能实例化对象,更加不可能通过ClassLoader调用上面两个方法。所以我们真正写代码的时候,是通过Class类中的getResource()和getResourceAsStream()方法,这两个方法会委托ClassLoader中的getResource()和getResourceAsStream()方法 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Jar中读取
*
* @throws IOException
* @author Forest Dong
* @date 2024/03/19 11:56
*/
public void getResource3() throws IOException {
InputStream is = this.getClass().getResourceAsStream("/application.yml");
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
String s = "";
while ((s = br.readLine()) != null)
System.out.println(s);
}
}

参考文档

从jar包中读取资源文件