Java OutputStream等效于getClass().getClassLoader().getResourceAsStream()

cra*_*aig 15 java file-io swing persistence properties

我试图存储对我的应用程序属性所做的更改.该.properties文件位于resources包中,该包与包含我的UI和模型的包不同.

我用以下方式打开了包裹:

this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")
Run Code Online (Sandbox Code Playgroud)

是否有一个功能等同于允许我在同一.Properties文件中持久更改属性类?

Ste*_*n C 24

通常,您不能将内容放回到从类加载器获得的资源中:

  • 类加载器资源通常是只读的; 即保存在只读文件/只读目录中.

  • 如果从JAR文件获取资源,则JAR文件不仅可以更新.(要"更新",您需要提取旧JAR的内容并使用更新的内容创建一个新的JAR.这与ZIP文件的结构有关...)

  • 在某些情况下,类加载器资源将被动态下载,并且无法将更改推送回您下载的位置.

即使你可以更新从类加载器获得的资源,这也是一个坏主意/坏习惯.

  • 使用用户的首选项"干扰"干净的应用程序安装.除此之外,这意味着无法与其他用户共享安装(除非您处理多个用户的首选项...).

  • 将应用程序安装为可写入存在安全问题,以便可以更新嵌入式首选项.想想病毒!想一个可能倾向于废弃其他用户偏好的用户!

  • 使用特定于用户的应用程序副本存在管理问题.如果用户必须安装自己的应用程序副本,那么也存在潜在的安全问题.

最后,这不是系统管理员(和受过教育的用户)期望软件行为的方式.最佳做法是以预期的方式处理用户首选项:

  • 对于以Java为中心的解决方案,请使用Java Preferences API.

  • 或者,您可以包含首选项的属性文件写入适合OS的用户可写目录.

  • 在Windows上,您可以使用特定于Windows的API将首选项存储在Windows注册表中(yuck).


Bal*_*usC 9

在'resources'包中,它包含我的UI和模型的包不同.

您应该使用上下文的类加载器.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
properties.load(classLoader.getResourceAsStream("resources/settings.properties"));
Run Code Online (Sandbox Code Playgroud)

是否有一个功能等同于允许我在同一.Properties文件中持久更改属性类?

你需要Properties#store()这个,可以采取一个OutputStream或一个Writer.首先,您需要获取URL属性文件并获取它,URI以便您可以File为此创建一个包装的文件FileOutputStream.

URL url = classLoader.getResource("resources/settings.properties");
properties.store(new FileOutputStream(new File(url.toURI())), null);
Run Code Online (Sandbox Code Playgroud)


Car*_*icz 5

当您将应用程序包装为JAR文件时,您的属性文件将是该JAR中的一个(可能是压缩的)文件,尝试写入您自己的JAR是一个坏主意.

getResourceAsStream()用于打开阅读资源,这些资源可以在类路径的任何位置.您无法写入URL或JAR内部,您只能写入文件,因此为输出提供相同的API没有意义.

找到一个您可以写入的目录,并在那里写下您的属性.

将属性从安装类路径(可能在JAR中)直接复制到文件(如果它尚不存在),作为应用程序启动时的第一个操作,这可能是个好主意.这将为您提供可以写入的属性文件,但此属性文件的主副本将来自您的项目可交付项.


Mic*_*rdt 2

听起来您想存储用户首选项。考虑使用Java Preferences API来实现这一点。

  • 这个答案怎么选呢?它不建议以其他方式回答问题,而是建议这样做。即使另一种方法更好,它也没有回答原来的问题。你应该做的是回答所问的问题,然后提出替代方法。 (11认同)