【问题标题】:How to get absolute path to file in /resources folder of your project如何在项目的 /resources 文件夹中获取文件的绝对路径
【发布时间】:2019-12-08 02:16:03
【问题描述】:

假设标准 maven 设置。

假设在您的资源文件夹中有一个文件abc

在Java中,请问如何获取文件的绝对路径?

【问题讨论】:

标签: java maven file resources


【解决方案1】:

真正有效的正确方法:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

现在类路径中文件的物理位置无关紧要,只要资源实际上是文件而不是 JAR 条目,就会找到它。

(看似显而易见的new File(resource.getPath()) 并不适用于所有路径!路径仍然是 URL 编码的!)

【讨论】:

  • 或者你可以这样做:new File(resource.toURI()).getAbsolutePath();(即我认为你不需要 Path 对象?)
  • 关于 toURI() 的好提示,这可以避免路径中的空格以 %20 的形式出现!
  • 谢谢!这几乎对我有用。但我不得不做出一项改变:YourClass.class.getClassLoader().getResource("abc");
  • 如果你愿意,你也可以选择new File(YourClass.class.getResource("abc").toURI().getPath())
  • 我不明白这对没有斜线的这么多人来说是如何工作的:.getResource("/abc")
【解决方案2】:

您可以使用ClassLoader.getResource 方法获取正确的资源。

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

虽然这可能不会一直有效,但更简单的解决方案 -

您可以创建一个File 对象并使用getAbsolutePath 方法:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();

【讨论】:

  • 限制使用的建议,因为它依赖于工作目录作为 maven 根目录。即使这样,您也应该使用target/classes/abc.txt 来引用该文件,因为这是 Maven 在处理后放置资源文件的规范位置(例如,maven-resources 插件可能在 abc.txt 上进行了属性替换)。最好通过类路径中的 getResource() 使用 abc.txt。
  • 如果最终用户将您的应用程序作为可执行 JAR 运行怎么办?然后根本不会有物理文件。这是您应该使用 getResource() 的另一个原因,例如根据你想用它做什么来打开它的输入流。
  • 这个可以作为正确答案删除吗? @Karol S 在下面回答 - 这应该是正确的答案(因此存在赞成票差异)
  • 错误答案。请参考@Karol 的以下回答
  • 我猜从技术上讲它是有效的。得到了正确的根路径,但它没有指向我的实际资源文件夹所在的模块。
【解决方案3】:

您需要指定从/开始的路径

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();

【讨论】:

  • 在我的情况下,它是一个 .png 文件,当我添加上述内容时,我得到的资源为空。请您告诉资源文件夹中存在的 .png 或 .pdf 文件如何处理?
【解决方案4】:

创建您需要的类的classLoader实例,然后您可以轻松访问文件或资源。 现在您使用该类的getPath() 方法访问路径。

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);

【讨论】:

    【解决方案5】:

    我们去绝对路径的路上有两个问题:

    1. 找到的位置不是源文件所在的位置,而是 类的保存位置。并且资源文件夹几乎肯定会位于某处 项目的源文件夹。
    2. 如果类在插件中或直接在工作区中的包中运行,则用于检索资源的相同函数的工作方式不同。

    以下代码将为我们提供所有有用的路径:

        URL localPackage = this.getClass().getResource("");
        URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
        String localDir = localPackage.getPath();
        String loaderDir = urlLoader.getPath();
        System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);
    

    这里研究了可用于资源文件夹本地化的两个函数。至于class,无论是静态获取还是动态获取都可以。


    如果项目不在插件中,代码如果在 JUnit 中运行,将打印:

    loaderDir = /C:.../ws/source.dir/target/test-classes/
     localDir = /C:.../ws/source.dir/target/test-classes/package/
    

    因此,要访问 src/rest/resources,我们应该在文件树上上下移动。两种方法都可以使用。注意,我们不能使用getResource(resourceFolderName),因为该文件夹不在目标文件夹中。我希望没有人将资源放在创建的文件夹中。


    如果该类在插件中的包中,则相同测试的输出将是:

    loaderDir = /C:.../ws/plugin/bin/
     localDir = /C:.../ws/plugin/bin/package/
    

    所以,我们应该再次在文件夹树中上下移动。


    最有趣的是在插件中启动包的情况。作为 JUnit 插件测试,对于我们的示例。输出是:

    loaderDir = /C:.../ws/plugin/
     localDir = /package/
    

    这里我们可以只结合两个函数的结果得到绝对路径。这还不够。在它们之间,我们应该放置类包所在位置的本地路径,相对于插件文件夹。可能,您必须在此处插入 srcsrc/test/resource 之类的内容。

    您可以将代码插入到您的代码中并查看您拥有的路径。

    【讨论】:

      【解决方案6】:

      返回一个文件或文件路径

      URL resource = YourClass.class.getResource("abc");
      File file = Paths.get(resource.toURI()).toFile(); // return a file
      String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path
      

      【讨论】:

        猜你喜欢
        • 2017-01-05
        • 2011-03-13
        • 1970-01-01
        • 2015-09-09
        • 2011-08-30
        • 2014-11-05
        • 2019-01-17
        • 2019-01-17
        • 1970-01-01
        相关资源
        最近更新 更多