什么是资源文件 ? 资源文件是打包到jar中的非 class 文件,如文本文件、图片等。
这里用一个例子讲解如何获取资源文件。
示例项目结构
这里使用 gradle 构建项目。
.
├── build.gradle
├── settings.gradle
└── src
└── main
├── java
│ └── com
│ └── example
│ └── Demo01.java
└── resources
└── test.txt
注意,虽然 test.txt 在 resources 目录下,但是打包到 jar 中时,resources 目录本身不会被打包,而 test.txt 会在 jar 的根目录下。
打包后的jar内容大致长这样:
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/Demo01.class
test.txt
test.txt 内容如下:
你好
Hello World
方法1: 使用 ClassLoader 的 getResource 方法
package com.example;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource("test.txt");
// URL url = ClassLoader.getSystemResource("test.txt"); // 这种方式也可以
String content = getContent(url);
System.out.println(content);
}
public static String getContent(URL url) throws Exception {
Path path = Paths.get(url.toURI());
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line + "\n");
}
return sb.toString();
}
}
执行结果:
你好
Hello World
方式2: 使用 使用 ClassLoader 的 getResources 方法
有时 classpath 下的多个路径/jar包中有同名文件,这些文件是都能读出来的。
package com.example;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources("test.txt");
// Enumeration<URL> urls = ClassLoader.getSystemResource("test.txt"); // 这种方式也可以
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
String content = getContent(url);
System.out.println(content);
}
}
public static String getContent(URL url) throws Exception {
Path path = Paths.get(url.toURI());
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line + "\n");
}
return sb.toString();
}
}
方案3: 使用 guava 库获取文本文件内容
本质上是对 ClassLoader 的 getResource 方法的封装。
若是基于 gradle 搭建项目,使用下面的方式引入依赖:
compile group: 'com.google.guava', name: 'guava', version: '28.2-jre'
代码示例:
package com.example;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import java.net.URL;
public class Demo {
public static void main(String[] args) throws Exception {
URL url = Resources.getResource("test.txt");
String content = Resources.toString(url, Charsets.UTF_8);
System.out.println(content);
}
}