我正在用java做一个项目,我需要添加和修改我的 运行时的文本文件,它在jar中分组。
我正在使用class.getResourceAsStream(filename)这个方法我们 可以从类路径中读取该文件。
我想写入相同的文本文件。
这可能是什么解决方案。 如果我无法更新jar中的文本文件还有其他解决方案吗? 感谢任何帮助。
答案 0 :(得分:3)
这里最简单的解决方案是不将文件放入jar中。听起来你正在把文件放在你的jar中,这样你的用户只需要担心一个文件包含与该程序相关的所有内容。这是一个人为约束,只会增加头痛。
有一个简单的解决方案仍然允许您只分发jar文件。在启动时,尝试从文件系统中读取文件。如果找不到,请使用在程序中编码的默认值。然后,当进行更改时,您可以将其写入文件系统。
答案 1 :(得分:2)
通常,您无法使用getResourceAsStream
更新找到的文件。它可能是JAR / ZIP文件中的文件......编写它需要重写整个JAR文件。它可能是由Url类加载器提供的远程文件。
为了您的理智(和良好实践),您不应尝试更新通过类路径访问的文件。如果需要,请从JAR文件(或其他)中读取文件,将其复制到常规文件系统中,然后更新副本。
我并不是说在所有情况下都不可能 。实际上,在大多数正常情况下,你可以做一些努力。但是,这不受支持,并且没有用于执行此操作的标准API。
此外,尝试更新资源可能会导致类加载器出现异常。例如,我希望JAR文件中的资源不会更新(从应用程序的角度来看),直到应用程序重新启动。但爆炸的JAR文件中的资源可能会更新......但新资源可能不会显示。
最后,有些情况下无法更新资源:
当用户没有对应用程序安装目录的写访问权限时。这对于正确管理的UNIX / Linux计算机来说是典型的。
从远程服务器获取JAR文件时,您可能无法写回更新。
当您使用任意自定义类加载器时,您无法知道应该存储更新资源的实际字节的位置,也无法存储它们。
答案 2 :(得分:1)
如果我无法更新jar中的文本文件,还有其他解决方案吗?
将信息存储在以下任何一项中:
PersistenceService
存储信息。这是我的demo. of the PersistenceService
。此外,如果您的用户同意受信任的applet(这似乎有点过分),您可以将信息写入user.home
的子目录。
答案 3 :(得分:1)
Java中的所有JAR重写技术看起来都很相似。打开Jar文件,读取它的所有内容,然后编写一个包含未修改内容的新Jar文件(以及你要修改的修改)。这种技术不适用于类路径上的Jar文件,更不用说你正在运行的Jar文件。
如果您决定必须这样做,Java World会有一些文章:
答案 4 :(得分:1)
避免将项目放入Jar文件的好解决方案是从用户主目录中的隐藏子目录中读取(如果存在)属性文件。逻辑看起来有点像这样:
if (the hidden directory named after my application doesn't exist) {
makeTheHiddenDirectory();
writeTheDefaultPropertiesFile();
}
Properties appProps = new Properties();
appProps.load(new FileInputStream(fileInHiddenDir));
...
... After the appProps have changed ...
...
appProps.store(new FileOutputStream(fileInHiddenDir), "Do not modify this file");
查看java.util.Properties,并记住它们有两种不同的加载和存储格式(key =基于值和基于XML)。选择最适合你的那个。