当代码在外部 jar 中时从资源文件夹读取文件

问题描述 投票:0回答:1

我正在创建一个库(它将是一个 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 的上下文中读取文件。

java spring-boot file jar classpath
1个回答
0
投票

您的

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 的。

© www.soinside.com 2019 - 2024. All rights reserved.