【问题标题】:Add txt files to a runnable JAR file将 txt 文件添加到可运行的 JAR 文件中
【发布时间】:2015-07-11 03:16:58
【问题描述】:

我正在尝试制作一个可运行的 jar 文件,但我的 .txt 文件有问题。

我的程序也有图像,但幸运的是我已经知道如何管理它们。我正在与他们一起使用这样的东西,它在 Eclipse 和 jar 中都可以正常工作:

logoLabel.setIcon(new ImageIcon(getClass().getResource("/logo.png")));

我的问题是当我在我的一门课上遇到这样的事情时:

try {
    employeeList =  (TreeSet<Employee>) ListManager.readFile("list/employeeList.txt");
} catch (ClassNotFoundException i) {
    i.printStackTrace();
} catch (IOException i) {
    i.printStackTrace();
}

这在我用来读取在 .txt 文件中序列化的列表的 ListManager 类中:

public static Object readFile(String file) throws IOException, ClassNotFoundException {
    ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
    Object o = is.readObject();
    is.close();
    return o;
}

我也有类似的方法写入文件。

我尝试了几种我在这里找到的组合:

How to include text files with Executable Jar

Creating Runnable Jar with external files included

Including a text file inside a jar file and reading it

我也尝试过使用斜杠,不使用斜杠,使用 openStream,不使用 openStream...但是或者我得到 NullPointerException 或者它根本无法编译...

也许是一些愚蠢的事情,或者是我对 URL 类如何工作的概念错误,我是编程新手...

非常感谢您的建议!

编辑:

又是我……Raniz 给出的答案正是我所需要的,而且效果很好,但现在我的问题是我用来写入文件的方法……

public static void writeFile(Object o, String file) throws IOException {
    ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
    os.writeObject(o);
    os.close();
}

try {
   ListManager.writeFile(employeeList.getEmployeeList(), "lists/employeeList.txt");
} catch (IOException i) {
   i.printStackTrace();
}

你能帮帮我吗?我不知道我应该用什么来代替 FileOutputStream,因为我觉得问题又来了,对吗?

非常感谢!

【问题讨论】:

  • 我想我知道你为什么要这么做。但这是一种错误的方法,您应该将您的外部文件(例如 config、txt 等)放在特定于您的应用程序的文件夹中。例如在 userhome/.yourappliactionname

标签: java jar


【解决方案1】:

问题是您试图将 JAR 存档中的文件作为文件系统中的文件来访问(因为这是 FileInputStream 的用途),但这是行不通的。

您可以将readFile 转换为使用 URL,并让 URL 为您处理打开流:

public static Object readFile(URL url) throws IOException, ClassNotFoundException {
    ObjectInputStream is = new ObjectInputStream(url.openStream());
    Object o = is.readObject();
    is.close();
    return o;
}

您还应该将您的代码放在 try 语句中,因为如果发生 IOException,它目前不会关闭流:

public static Object readFile(URL url) throws IOException, ClassNotFoundException {
    try(ObjectInputStream is = new ObjectInputStream(url.openStream())) {
        Object o = is.readObject();
        return o;
    }
}

try {
    employeeList =  (TreeSet<Employee>) ListManager.readFile(getClass().getResource("/list/employeeList.txt"));
} catch (ClassNotFoundException i) {
    i.printStackTrace();
} catch (IOException i) {
    i.printStackTrace();
}

我也有类似的方法写入文件。

如果文件在 JAR 中,这将不起作用,因此您可能应该考虑将文件放在 JAR 之外。

【讨论】:

  • 非常感谢!它工作得非常好,并且与 JAR 中的文件一起使用。但现在我的问题在于我用来写入文件的方法......我已经编辑了我的问题以显示我在做什么。
  • 答案是您不应该将需要更改的文件保留在 JAR 中。如果问题在于分发,请创建文件和 JAR 的 ZIP 并分发它。
【解决方案2】:

是的,如果你想从 jar 文件中读取资源,你不应该使用FileInputStream。或许你应该添加一个readResource 方法:

public static Object readResource(Class clazz, String resource)
    throws IOException, ClassNotFoundException {
  try (ObjectInputStream is =
           new ObjectInputStream(clazz.getResourceAsStream(resource))) {
     return is.readObject();
  }
}

(我还建议更新您的 readFile 方法以使用 try-with-resources 块 - 目前如果出现异常,您不会关闭流...)

请注意,当您说“我也有类似的方法来写入文件”时 - 您将无法轻松地写入 jar 文件中的资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2017-03-22
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    相关资源
    最近更新 更多