如何让我的java项目在不使用绝对路径的情况下使用某些文件?

问题描述

我编写了一个项目,其中一些图像用于应用程序的外观,并且在此过程中将创建和删除一些文本文件。我只使用了所有使用过的文件绝对路径来查看项目如何工作,现在它完成了我想将它发送给其他人。所以我要问的是如何将这些文件链接到项目,以便其他人不必设置相对于他们的计算机的绝对路径。类似于,将包含必要文件的最终 jar 文件转换为 zip 文件,然后该人提取 zip 文件并导入 jar 文件,当运行它时,程序运行没有任何问题。 顺便说一下,我使用 ImageIcon 类添加图像。

我正在使用日食。

解决方法

对于您只想阅读的文件,例如应用图标中使用的图像:

  • 以与传送类文件相同的方式传送它们:在 jar 或 jmod 文件中。
  • 使用 YourClassName.class.getResource.getResourceAsStream 阅读这些内容。 它们不是文件,任何需要 File 对象的 API 都无法工作。不要使用这些 API(它们很糟糕) - 好的 API 使用 URI、URL 或 InputStream,这可以很好地处理此问题。

示例:

package com.foo;

public class MyMainApp {

    public void example() {
        Image image = new Image(MyMainApp.class.getResource("img/send.png");
    }

    public void example2() throws IOException {
        try (var raw = MyMainApp.class.getResourceAsStream("/data/countries.txt")) {
            BufferedReader in = new BufferedReader(
              new InputStreamReader(raw,StandardCharsets.UTF_8));
            for (String line = in.readLine(); line != null; line = in.readLine()) {
              // do something with each country
            }
        }
    }
}

这个类文件将在您的 jar 中作为 /com/foo/MyMainApp.class 结束。同一个 jar 文件还应该包含 /com/foo/img/send.png/data/countries.txt。 (注意如何开始传递给 getResource(AsStream) 的字符串参数可以以斜杠开头或不以斜杠开头,这控制它是相对于类的位置还是相对于 jar 的根目录。您选择哪个更好).

对于您的应用将创建/更新的文件:

  • 这不应该靠近您的 jar 文件所在的位置。那是 80 年代后期/愚蠢的窗户思维。应用程序位于(或应该位于)您该应用程序无法写入的位置。一般来说,应用程序的安装目录是只读的,当然不应该包含用户的文档。这些应该在“用户主页”中,或者可能在例如“我的文档”。

示例:

public void save() throws IOException {
    Path p = Paths.get(System.getProperty("user.home"),"navids-app.save");
    // save to that file.
}