gpt4 book ai didi

java - 导出的 JAR 无法读取本地文件

转载 作者:行者123 更新时间:2023-12-01 09:35:00 24 4
gpt4 key购买 nike

我的 Java 应用程序在名为“assets”的顶级文件夹中有一个名为“classes”的本地文件(简单的 List<String> )。当我从 Eclipse 运行下面的代码时,读取文件没有问题。

try { // read in classes from local file
ObjectInputStream inputStream =
new ObjectInputStream(new FileInputStream("assets\\classes".replace("\\", "/")));
listOfClasses = (List<String>) inputStream.readObject();
System.out.println("*** Reading local copy of classes file ***");
inputStream.close();
} catch (FileNotFoundException e) { e.printStackTrace();
} catch (ClassNotFoundException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); }

当我将应用程序导出为 JAR 并在另一台计算机上运行它时,我得到 java.io.FileNotFoundException在第三行。我将“assets”文件夹添加到构建路径中,因此它应该位于 JAR 中。

有人知道这里出了什么问题吗?

最佳答案

FileOutputStream 仅打开本地文件。它应该是绝对目录(/home/user/...c:\temp\...)或相对于当前目录。例如,在 Windows 上,默认情况下这是包含 JAR 的目录。

如果您打算将 classes 文件打包到 JAR 中,那么您应该使用 getResourceAsStream,如 @guleryuz 提到的。该路径应该是从 CLASSPATH 根(即 JAR 文件的根)开始的绝对路径,例如 "/asset‌​s/classes",或者(更好)相对于包的包调用类。

说到类,我强烈建议不要使用getClass(),因为它是一种多态方法。有两种方法可以获取类:通过在对象上调用 getClass() 或访问静态 class“字段”。如果您有一个名为 myObjectMyClass 实例,则 myObject.getClass()MyClass.class 本质上是一样的东西。但!如果您的类被另一个包中的类覆盖,例如 TheirClass,那么对于 TheirClass 的实例,getClass() 将返回TheirClass.class,即使您从您的代码调用getClass()。因此,除非您的类被声明为final,否则使用getClass().getResource... 始终是一个坏主意,因为您永远不知道何时有人覆盖您的类。而且你不应该知道,甚至不应该关心!

考虑到所有这些,比如说,您在名为 my.package 的包中有一个名为 MyClass 的类。 JAR 可能具有以下结构:

my/
package/
MyClass.class
assets/
classes

然后,调用 MyClass.class.getResourceAsStream("assets/classes") 应该可以解决问题。或者,也可以是 MyClass.class.getResourceAsStream("/my/package/assets/classes")。请注意,绝对路径从项目目录开始,其中您可能有srcsrc/main或您的构建系统使用的任何目录。它是相对于 CLASSPATH 根的(没错,绝对路径是相对于 CLASSPATH 根的,即使这听起来令人困惑)。也就是说,它从您的包所在的目录开始。

最后但并非最不重要的一点是,如果您使用类似 Maven 的构建系统(例如 Maven 或 Gradle),那么 Java 源代码将转到 src/main/java,但资源文件将转到 src/main/java就像你的文件一样,转到src/main/resources。它们最终位于 JAR 文件中完全相同的位置。即src/main/java/package/MyClass.java编译为package/MyClass.class,以及src/main/resources/package/assets/classes 进入package/assets/classes。但是为了让构建系统确定如何处理您的文件,您必须将它们放入正确的目录中:*.java 转到 java,资源转到资源

因此,假设采用类似 Maven 的约定,项目结构应该是

src/
main/
java/
my/
package/
MyClass.java
src/
main/
resources/
my/
package/
assets/
classes

给定这样的结构,您将获得一个具有如上结构的 JAR 文件。看起来有点疯狂,但是一旦掌握了它就会非常有用。

如果您没有使用类似 Maven 的构建系统,那么我不知道如何配置 Eclipse。不同的 IDE 可能有自己的约定,我一直将 Maven 与 Eclipse 结合使用。例如,某些 IDE 喜欢将 Java 源代码和资源放入同一目录树中。

关于java - 导出的 JAR 无法读取本地文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39060883/

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