如何重新加载 jar 上的属性文件

How to reload a properties file on a jar

我有一个在 Eclipse 上开发的 java 应用程序,我想生成它的可执行 jar。首先,我发现了 jar 无法管理进入 FileInputStream 的路由的问题,所以我决定将 FileInputStream 更改为 getClass().getResourceAsStream()。问题是我必须在执行时覆盖属性文件,但是 getResourceStream() 没有正确重新加载,因为它必须在缓存或其他东西中。我尝试了在该论坛中找到的几种解决方案,但其中 none 似乎有效。

我使用 FileInputStream 加载属性的原始代码是:

private Properties propertiesLoaded;
private InputStream input;
this.propertiesLoaded = new Properties();
this.input = new FileInputStream("src/resources/config.properties");
propertiesLoaded.load(this.input);
this.input.close();

这似乎在 Eclipse 中运行得很好,但在 jar 中却不行。我用这个论坛的信息尝试了这种方法:

this.propertiesLoaded = new Properties();
this.input = this.getClass().getResourceAsStream("/resources/config.properties");
propertiesLoaded.load(this.input);
this.input.close();

问题是当程序尝试更新属性文件时,它似乎没有正确地重新加载它。我可以看到 属性 已被编辑,但再次阅读时 returns 是旧值。覆盖 属性 的代码是:

private void saveSourceDirectory(String str) {
    try {
        this.input = this.getClass().getResourceAsStream("/resources/config.properties");
        propertiesLoaded.load(this.input);
        propertiesLoaded.setProperty("sourceDirectory", str);
        propertiesLoaded.store(new FileOutputStream("src/resources/config.properties"), null);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我的问题是:

我认为更新 jar(或 zip)中的文件的唯一方法是再次提取、修改和压缩它。可能你不能用 运行 罐子做到这一点。

当你这样做的时候:

propertiesLoaded.store (new FileOutputStream ("src / resources / config.properties"), null);

您可能会收到 FileNotFoundException,因为您无法使用文件 API,就像您无法使用 FileInputStream 加载属性一样。

最好的解决方案可能是将属性存储在 jar 之外的某个地方或使用 Java 首选 API。

相关:https://coderanch.com/t/616489/java/modify-Properties-file-JAR

关于你的第一个问题:你不应该这样做。一种常见的方法是在可执行 jar 中使用内置配置,并可选择将配置文件作为参数传递。将配置更改存储回 jar 不是一个好主意,因为这意味着修改 运行 二进制文件。

第二个问题:实现此类功能的常用方法是向您的配置文件添加更改侦听器。这可以使用 java.nio.file package 来完成: https://docs.oracle.com/javase/tutorial/essential/io/notification.html