当项目转换为可执行jar时,序列化文件不起作用?

我使用eclipse中的export to jar选项将我的java项目变成了一个可执行jar。 jar按预期运行,但它不使用任何序列化文件。 我可以从GUI清楚地看到。 可能是这个问题的原因,我该如何解决?

我看到了这个相关的问题 – 为什么我的JAR文件没有创建序列化?

但它并没有告诉我如何解决这个问题。 看起来你无法将文件夹打包到jar中。 为什么? 因为代码可能会意外/故意继续将数据添加到该文件夹​​中并使整个jar占用硬盘?

如何创建某种结构,我将可执行jar及其序列化文件夹打包?

回答这个问题:

如何创建某种结构,我将可执行jar及其序列化文件夹打包?

一种常见的方法是有一个明确定义的位置来存储序列化文件,设置等,而不依赖于程序的执行位置。 通常它是用户的主目录,或者是Windows的应用程序数据。 我使用此代码存储我的应用程序设置:

String home = System.getenv("APPDATA"); if (StringUtils.isEmpty(home)) { home = System.getProperty("user.home"); } CONFIG_HOME = new File(home, ".myProgram").getAbsoluteFile(); CONFIG_HOME.mkdirs(); 

因此在Windows上它将使用AppData,在* nix系统上它将使用用户的家。 myProgram前面的点是隐藏在* nix平台上的,这是一种常见的做法。

编辑您的评论中的问题:

在我的linux机器上没有APPDATA env变量,所以这段代码将创建一个目录/home/myUser/.myProgram 。 在Windows上,它将类似于c:/Users/myUser/AppData/Local/.myProgram 。 在MacOSX上,不知道。

您需要使用相同的路径来读取序列化文件作为eclipse中的代码。

因此,您创建一个包含序列化对象的目录的属性文件。 然后,对于您的JAR和我们的项目,这是相同的。

另见: http : //www.mkyong.com/java/java-properties-file-examples/

您可以使用

 AClass.class.getResource(String str); //or AClass.class.getResourceAsStream(String str); 

AClass:你的一个class级。

str:您要读取的文件位置。

例如;

如果您的类层次结构如下所示:

 +src +-com +-test |-AClass.java +-util +-PrintUtil.java +-resources |-Bouble.png |-Mouse.png +-Ocean.png 

并且对于阅读“Mouse.png”图像,您可以通过多种方式实现:

 AClass.class.getResource("/resources/Mouse.png"); //or PrintUtil.class.getResource("../resources/Mouse.png"); ... 

在使用/运行jar文件时,不能在jar文件中写入。 当您将jar文件放在类路径中或者直接从jar运行程序时,jar将被您的jvm锁定,因此它不允许您更新当前使用的相同jar文件。

如果您的类位于文件夹中,而不是存档(您正在使用),那么人们给出的使用资源作为流的解决方案将起作用。

作为存档,您无法直接更新它,您需要执行以下步骤(由您自己或第三方API),
在临时位置提取
更新文件
重新存档

现在,当jar文件被锁定时,您将无法进行第三次操作,这甚至都不安全。 作为一个例子,当你运行一个jar文件时,尝试重命名它,它不会发生,如果它发生了,jar文件还没有被jvm锁定,它会在你调用jar里面的类时被锁定文件。
为了更好,更安全地进行序列化和文件保存,请查看: java.util.prefs.Preferences