gpt4 book ai didi

java - 从jar里面获取资源文件

转载 作者:行者123 更新时间:2023-12-02 01:26:40 25 4
gpt4 key购买 nike

当应用程序打包到 jar 中时,我需要从应用程序的根目录中获取资源。我的项目是这样的:

ProjectRoot
resource.txt //want to access from here
src
main
java
package1
package2
package3
Main.java
target
app.jar
classes
resource.txt //works when here
package1
package2
package3
Main.class

我使用这个代码:

Path path = Paths.get("resource.txt");

当在打包成 jar 之前运行时,它发现文件很好(在 ProjectRoot 内)。运行jar时,找不到它,并将此路径转换为target/resource.txt

这段代码:

BufferedReader br = new BufferedReader(new InputStreamReader(new Main().getClass().getClassLoader().getResourceAsStream(
"resource.txt")));

在打包之前运行时,会查找 target/classes 中的资源。打包后,它声称从 .../target/app.jar!/resource.txt 获取资源。

这段代码:

BufferedReader br = new BufferedReader(new InputStreamReader(new Main().getClass().getClassLoader().getResourceAsStream(
"/resource.txt")));

我无法理解在哪里寻找资源,但它似乎不是 ProjectRoot

我想要做的就是将资源放入 ProjectRoot 中,并能够从外部 jar(从 IDE 运行类文件时)和内部(将文件打包到使用 Maven 的 jar 文件)。

编辑:我需要该代码可以用于打包前和打包后。含义:如果我从 IDE 内部运行 Main.java,它将获取资源;如果我将所有内容打包到 JAR 中并运行 JAR,它将获得资源 - 全部使用相同的代码。

最佳答案

Maven 使用名为 Standard Directory Layout 的东西。如果您不遵循此布局,则插件将无法正确完成其工作。从技术上讲,您可以将 Maven 配置为使用不同的目录,但 99.999% 的情况下这是不必要的。

此布局的特点之一是生产文件进入:

  • <project-dir>/src/main/java
    • 全部 *.java文件
  • <project-dir>/src/main/resources
    • 所有非 *.java文件(即资源)

当您构建项目时,Java 源文件将被编译并生成 *.class文件被放入 target/classes目录;这是由 maven-compiler-plugin 完成的。同时,资源文件是从src/main/resources复制的。进入target/classes以及; maven-resources-plugin对此负责。

注意:请参阅 Introduction to the Build Lifecycle有关阶段以及哪个阶段执行哪些插件的更多信息。这个Stack Overflow question可能也有用。

当您从 IDE 启动应用程序时(可能通过 exec-maven-plugin )target/classes目录放在类路径上。这意味着 src/main/java 中的所有编译类。以及从 src/main/resources 复制的所有资源可以通过类路径使用。

然后,当您将应用程序打包到 JAR 文件中时, target/classes 中的所有文件添加到生成的 JAR 文件中(由 maven-jar-plugin 处理)。 这包括从 src/main/resources 复制的资源。当您使用此 JAR 文件启动应用程序时,资源仍然可以通过类路径使用,因为它们嵌入在 JAR 文件中。

制作 resource.txt在类路径上可用,只需移动:

<project-dir>/resource.txt

致:

<project-dir>/src/main/resources/resource.txt.

然后你可以使用Class#getResource/resource.txt作为道路和一切都应该适合你。 URL返回者 getResource会有所不同,具体取决于您是否针对 target/classes 执行或针对 JAR 文件。

针对 target/classes 执行时你会得到类似的东西:

file:///.../<project-dir>/target/classes/resource.txt

当对 JAR 文件执行时,你会得到类似的结果:

jar:file:///.../<project-dir>/target/projectname-version.jar!/resource.txt

注意:这一切都假设 resource.txt实际上应该是资源而不是外部文件。一旦部署在 JAR 文件中,资源通常是只读的;如果您需要可写文件,那么您可以使用该文件的指定位置(例如用户主目录中的文件夹)。通常通过 java.io.File 访问外部文件或java.nio.file.* 。请记住,资源与普通文件不同。

现在,如果你输入 resource.txt直属<project-dir>这对 Maven 来说毫无意义。它不会被复制到 target/classes或者最终出现在 JAR 文件中,这意味着该资源在类路径上永远不可用。重申一下,所有资源都归 src/main/resources 管辖。

<小时/>

查看 java.lang.Class#getResource(String) 的 Javadoc有关路径的更多信息,例如何时使用前导 /以及什么时候不可以。该链接指向 Java 12 的 Javadoc,其中包含有关资源和模块(JPMS/Jigsaw 模块,而不是 Maven 模块)的信息;如果您不使用模块,则可以忽略文档的该部分。

关于java - 从jar里面获取资源文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56779816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com