【问题标题】:How to get the absolute path for the resources directory in Java?如何获取Java中资源目录的绝对路径?
【发布时间】:2016-09-26 05:15:17
【问题描述】:

我正在尝试找到一种方法来获取我的 junit 测试中资源文件夹的绝对路径。

我的疑问不是在资源文件夹中获取文件(我现在该怎么做)但是获取资源文件夹的路径。

例如,如果我的资源文件夹中的文件具有以下结构:

/opt/project/view/api/target/classes/
/opt/project/view/api/target/classes/file_in_resources.txt

我想获得/opt/project/view/api/target/classes/ 的位置,而不使用像这样丑陋的东西:

URL location = this.getClass().getResource("/file_in_resources.txt");
String path = location.getPath();
String rightPath = path.substring(0, path.lastIndexOf("/"));

想法是有一个像this.getClass().getResourcesPath()这样的方法,但是这种方法不存在。

怎么办?

【问题讨论】:

  • 答案是,根本不要这样做。当您尝试从 .jar 文件运行程序时,资源将位于 .jar 文件中,根本不是单独的文件。无论您想做什么,还有另一种更好的方法,它不需要将资源位置转换为文件路径。
  • @VGR,这应该是一个答案
  • @VGR 如果它只是用于单元测试,那不是问题吗?
  • @Tobb 如果程序要从 .jar 文件运行,则需要针对 .jar 文件运行单元测试。
  • 现在怎么办?通常不会针对 jar 文件运行单元测试,这些测试不包括在内。

标签: java unit-testing testng


【解决方案1】:

如果一个人应该“有这个问题”,可能会有关于利弊的长期哲学讨论。但是,如果您也像我一样碰到它,那么如果您想使用 当前的 Java 样式(假设:您是 file_in_resources.txt 位于适当的 Unittest 标准文件夹 src/test/resources 中):

private String readFileFromResourcesAsString(String fileName) throws IOException {
    Path filePath = Paths.get("./src/test/resources/yourCustomPathHere/" + fileName);
    return Files.lines(filePath).collect(Collectors.joining());        
}

如果您真的想坚持使用文件夹 view/api/target/classes/,您可以使用带有 java.net.URI 的 Paths.get-statement(如 Chetan Jadhav CD已经提到):

Paths.get(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI());

该解决方案利用了 NIO.2 周围的最新 Java-API(参见 oracle tutorials here),例如

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

还有一些 Java 8 流 API 部分,用于将文件内容读入字符串(您可以根据需要更改此部分:))。

Paths.get(".")

这里很关键 - 无论您使用什么操作系统(Windows、Linux、MacOS),它都会透明地为您提供当前工作目录。

如果您是 Spring 用户,那么整个事情就更简单了!见so answer here

【讨论】:

  • 这是一个糟糕的答案。 Paths/files/absolutepath 技术与 getClass/getResource 非常不同。答案与问题无关。
  • 对不起,但我不明白你的意图:这个答案远非大肆抛出,它试图全面解释另一种 - 当前的 Java 风格 - 解决方案。问题所有者(除了接受这是最佳答案之外)只提到“像this.getClass().getResourcesPath() 这样的方法”,但他的代码与此相去甚远——根本没有这样的方法。因此,提供一个可行的解决方案似乎并不像我的答案那么糟糕。因此,我也真的没有得到你的反对,这只是粗鲁 - 抱歉。
  • 在 Java 中有几种情况,用于查找当前目录或当前资源目录,或当前类加载器目录或当前插件目录,或 jar 中的当前目录(对 jar 重复上述所有操作)的操作不同.任何与主题不完全相同的答案都是无用的。显然,问题作者想要资源目录,而您提出了当前目录。作者承认您的答案这一事实可能意味着他没有看到更好的答案。或者,您的弹簧参考有效。
【解决方案2】:

如果您的测试类位于同一资源文件夹中,您可以尝试:

URL location = TestClass.class.getProtectionDomain().getCodeSource().getLocation();
String path = location.getPath();
String rightPath = path.substring(0, path.lastIndexOf("/"));

如果资源文件夹不同,您可以根据其相对位置导航到它,以测试类的位置(使用上面的代码获得)作为参考点。

String adjustedPath = rightPath+"/resources";

【讨论】:

  • 对我来说这个问题是,那个 class.getProtectionDomain().getCodeSource().getLocation() 只是指向 c:/yourPathHere/yourprojectNameHere/target/classes
  • OP 在他的问题描述的第一句话中说他想要资源文件夹的绝对路径。因此,在这种情况下,基于 Windows 的机器上的路径将从驱动器 C:/ 的根目录开始。 rightPath 变量将指向 TestClass 所在的位置。但是,我们可以修改这个变量并在知道资源文件夹的相对位置的情况下对其进行调整,例如通过截断它的/target/classes 部分并在截断字符串的末尾附加/resources。这能解决您的问题吗?
  • 另一个可怕的答案。 Paths/files/absolutepath 技术与 getClass/getResource 非常不同。答案与问题无关。
【解决方案3】:

如果您在单元测试的上下文中,那么直接引用文件是没有问题的,因为您知道它在哪里并且它不会去任何地方。您可以获取文件 url,然后使用Path 在文件夹结构中向上导航,直到找到正确的文件夹。

final URL location = this.getClass().getResource("/file_in_resources.txt");
final Path path = Paths.get(location.getPath());
final String folder = path.getParent() //getParent().getParent()...
                          .toString();

【讨论】:

    【解决方案4】:
    猜你喜欢
    • 2019-03-12
    • 2018-12-27
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2020-11-26
    • 1970-01-01
    相关资源
    最近更新 更多