Java获取资源路径

Java获取资源路径


在 Java 中,获取资源文件的路径可以通过以下几种方式实现,具体方法取决于资源的存放位置和环境:

1. 获取方式


1.1 ClassLoader.getResource()

  • 使用类加载器来获取资源的路径,资源需要存放在类路径(通常是 src/main/resources)下。返回的是 URL 对象。
1
2
3
4
5
6
7
8
9
@Test
void getPathByClassPathResource(){
// 使用类加载器资源的URL
URL url = getClass().getClassLoader().getResource("static/font/simsun.ttc");
// 获取资源的路径
String path = url.getPath();
// 使用类加载器来获取资源的路径并打印出来
System.out.println("类加载器来获取资源的路径: "+path);
}

1.2 Class.getResource()

  • 使用类对象获取资源路径,可以加载当前类包下或根目录的资源。与 ClassLoader.getResource() 不同,路径可以以 / 开头,表示从类路径根目录开始。
1
2
3
4
5
6
7
8
9
@Test
void getPathByClass(){
// 使用类对象获取资源路径,"/" 表示从根目录开始获取资源
URL url = getClass().getResource("/static/font/simsun.ttc");
// 提取资源路径
String path = url.getPath();
// 输出路径信息
System.out.println("类对象获取资源路径: "+path);
}

1.3 File

  • 直接通过 File 类获取文件的绝对路径。适用于资源在文件系统中的情况(如项目的相对路径、绝对路径等)。
1
2
3
4
5
6
7
8
9
@Test
void getPathByFile(){
// 创建一个File对象,指向资源文件系统中的一个特定文件
File file = new File("src/main/resources/static/font/simsun.ttc");
// 获取文件的绝对路径
String path = file.getAbsolutePath();
// 打印文件的绝对路径
System.out.println("文件对象获取资源路径: "+path);
}

1.4 Paths.get()Files

  • 使用 java.nio.file.Paths 结合 Files 来获取文件路径,适用于从文件系统加载资源。
1
2
3
4
5
6
7
8
@Test
void getPathByPaths(){
// 创建一个Path对象,指向资源文件
Path path = Paths.get("src/main/resources/static/font/simsun.ttc");
// 将Path对象转换为绝对路径字符串
String absolutePath = path.toAbsolutePath().toString();
// 打印Path对象的绝对路径
System.out.println("Path对象获取资源路径: "+absolutePath);

1.5 System.getProperty()

  • 可以通过系统属性获取 Java 运行时的一些基本路径,比如用户目录或项目的当前工作目录。
1
2
3
4
5
6
7
8
9
@Test
void getPathBySystem(){
// 获取项目根目录
String userDir = System.getProperty("user.dir");
// 拼接项目中的资源文件路径
String path = userDir + "/src/main/resources/static/font/simsun.ttc";
// 打印通过系统属性获取的资源路径
System.out.println("系统属性获取资源路径: "+path);
}

这些方法适用于不同的场景,具体取决于资源文件的存储位置。如果资源位于类路径下(如 src/main/resources),则使用 ClassLoaderClass.getResource() 更合适;如果资源在文件系统中,则可以直接使用 File 类或 Paths 获取路径。

2. 在Windows和Linux下测试


最近在开发一个项目,需要加载资源路径,但是在部署到Linux服务器时确报指定的路径文件找不到。刚好自己的电脑上安装了Ubuntu,所以我分别在Windows和Linux系统下进行了测试。

2.1 Windows测试结果

image-20240908090635746

2.2 Linux测试结果

image-20240908171525205

最后一种System.getProperty()路径获取在不同系统有偏差,不能做到很好的兼容。

3. Linux下的异常问题


通过实际项目部署发现,项目在读取jar包的情况下。上面涉及的五种方法均出现问题,不能正确获取jar表中的文件路径。通过查看日志发现路径莫名奇妙多出一些,导致找不到文件。

image-20240909202818777

  • jar包结构
  • image-20240909204007669

3.1 解决方法

3.1.1 使用idea中的源路径

实际的测试发现使用idea中的源路径static/font/simsun.ttc可以找到jar中的文件,其实这idea中的源路径就是jar包中的相对路径。

通过解压jar包发现simsun.ttc存在BOOT-INF >static>font,此外项目中java目录下编辑的代码以及resources下的文件夹和文件全部存放在classes下。

image-20240909205107191
  • SpringBoot Jar包的大致结构以及存储内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
spring-boot-app.jar

├── META-INF
│ └── maven
| └───camellia
| └───PrintFounction
| └───pom.xml

├── BOOT-INF
│ ├── classes
│ │ ├── print
│ │ │ ├── controller
| | | ├── service
| | | ├── mapper
| | | └── utils
| | ├── static
| | | └── font
| | └── templates
│ │
│ └── lib
│ └── spring-boot-starter-xxx.jar(maven中引入的jar包)

└── org/
└── 第三方库的类文件

3.1.2 getResourceAsStream

使用LoadCacheFile.class.getClassLoader().getResourceAsStream(filepath)获取文件路径。

这个是在Linux和Windows都通用的方法。

3.1.3 将jar中的文件拿出单独存放

可以将运行所需要的外部资源,如我这里的渲染字体拿出来单独存储在机器的一个目录中,通过在配置文件中配置路径,在需要的地方获取配置的路径即可。