我正在创建一个库(它将是一个 jar 文件)。我有一个正在运行的应用程序“A”,它依赖于我正在创建的这个库 - “B.jar”。 在 A 的 src/resources 文件夹中,我们有一个文件,例如“test.yaml”。 B 有一些要从 A 调用的代码,文件路径作为字符串一起传递。 B 中的代码应该能够读取文件内容并进行进一步处理..
这是我在库“B”中的代码
private TestDataVO getTestDataVO(String testFileName) {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(this.testFileName);
testData = ymlMapper.readValue(is, TestDataVO.class);
return testData;
}
“A”中的来电代码:
getTestDataVO("test.yaml")
我的代码的问题是 this.getClass.getClassLoader() 给出了“B”而不是“A”的类路径,因此无法读取“A”类路径上的 test.yaml。我怎样才能修改 getTestDataVO 以从“A”的类路径中读取文件。发送绝对路径不是一种选择。我很乐意进一步澄清。
PS.- 我尝试搜索其他答案,所有这些答案都指向 jar 中存在的资源文件并从调用应用程序读取。我正在尝试调用应用程序的另一种方式,从 jar 的上下文中读取文件。
您的
getTestDataVO
代码不关心它如何获取数据,只要它获取数据即可。
因此,
getTestDataVO
的正确参数类型不是String
。相反,它应该是 byte[]
,或 InputStream
,或可能两者都是。
还要注意,到目前为止你所做的是错误的(它是
MyClass.class.getResource
,而不是getClass().getClassLoader()...
。getClassLoader()
部分是毫无意义的打字并且在极少数情况下会中断。getClass()
在子类化时中断。因此为什么这是唯一的此类任务的正确方法)。
假设您创建了输入流。然后你可以这样做:
private TestDataVO getTestDataVO(InputStream is) {
try {
testData = ymlMapper.readValue(is, TestDataVO.class);
} finally {
is.close();
}
}
// and to call:
getTestDataVO(MyClass.class.getResourceAsStream("test.yaml"));
或者甚至可能只使用
getResource
:
private TestDataVO getTestDataVO(URL resource) {
try (var is = resource.openStream()) {
testData = ymlMapper.readValue(is, TestDataVO.class);
}
}
// and to call:
getTestDataVO(MyClass.class.getResource("test.yaml"));
在这两个方面,关键的方面是 A 最终使用 its 加载器找到这个资源,然后将找到的资源传递给 B,而不是让 B 找到它,这很棘手,因为它是 A 类路径的一部分,不是 B 的。