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

How to have my java project to use some files without using their absolute path?

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

添加图像

我正在使用 eclipse。

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

  • 以与运送 class 文件相同的方式运送它们:在您的 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
            }
        }
    }
}

这个 class 文件将以 /com/foo/MyMainApp.class 的形式保存在您的 jar 中。同一个 jar 文件还应该包含 /com/foo/img/send.png/data/countries.txt。 (请注意,您传递给 getResource(AsStream) 的字符串参数如何以斜杠开头,这控制着它是相对于 class 的位置还是相对于 jar 的根。您的选择你觉得更好的东西)。

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

  • 这不应该在您的 jar 文件所在的位置附近。那是 80 年代后期/愚蠢的 windows 想法。应用程序位于(或应该位于!)该应用程序无法写入的地方。一般来说,应用程序的安装目录是只读的,而且肯定不应该包含用户的文档。这些应该在 'user home' 或者可能在例如`我的文档'。

示例:

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