You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven父子模块项目中如何正确指定文件相对路径?

解决Maven多模块项目中资源文件路径加载问题

你的问题本质是混淆了开发时的文件系统路径和运行时的类路径——本地IDE运行时默认工作目录是项目根目录de-service,所以你写的相对路径能找到文件;但部署后,程序的工作目录变成了de-service-web模块的运行目录,而且Maven打包后资源文件已经被整合到classpath中,不再是原来的文件系统路径了。

下面是两种可靠的解决方案,优先推荐第一种:

1. 使用类路径加载资源(强烈推荐)

因为testModel.model位于de-service-web/src/main/resources/model/下,Maven打包时会自动把这个目录下的文件复制到target/classes/model/,最终会被打包到jar/war的classpath根目录下的model文件夹里。所以你可以通过类加载器直接读取这个资源,完全不用关心文件系统的具体路径:

普通Java项目示例

// 方式1:通过当前类的类加载器读取(适合非静态方法)
InputStream modelStream = getClass().getResourceAsStream("/model/testModel.model");
if (modelStream == null) {
    throw new FileNotFoundException("无法在classpath中找到testModel.model");
}
// 后续通过modelStream处理文件内容,比如读取为字符串或字节数组

// 方式2:通过上下文类加载器读取(更灵活,适合静态方法)
InputStream modelStream2 = Thread.currentThread().getContextClassLoader()
    .getResourceAsStream("model/testModel.model");

小提示:getClass().getResourceAsStream()的路径如果以/开头,是相对于classpath根;如果不带/,是相对于当前类所在的包路径。而上下文类加载器的路径默认就是相对于classpath根,所以不用加开头的/。

Spring/Spring Boot项目示例

如果你的项目是Spring相关的,可以用ClassPathResource来简化操作:

ClassPathResource resource = new ClassPathResource("model/testModel.model");
// 注意:如果资源在jar包内,不要用getFile()(会抛出IO异常),优先用getInputStream()
InputStream modelStream = resource.getInputStream();

2. 不推荐:通过工作目录拼接路径(仅适用于特殊场景)

如果你一定要用文件系统路径(非常不建议,因为部署环境的工作目录可能和本地完全不一致),可以先获取当前程序的工作目录,再拼接相对路径:

String userDir = System.getProperty("user.dir");
// 假设部署后工作目录是de-service-web,拼接路径
String modelPath = userDir + "/src/main/resources/model/testModel.model";
// 但这种方式极其不可靠——比如打包成jar后,服务器上根本不存在src目录

为什么原来的路径会失效?

  • 本地IDE运行时,默认工作目录是项目根de-service,所以de-service-web/src/main/resources/model/testModel.model是有效的文件系统路径。
  • 部署到服务器后,程序的工作目录可能是de-service-web模块的目录,或者已经打包成jar/war,此时原来的文件系统路径已经不存在,资源已经被嵌入到包内的classpath中,只能通过类加载器读取。

内容的提问来源于stack exchange,提问作者user697911

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:25:39