Java OutputStream 相当于 getClass().getClassLoader().getResourceAsStream()

2022-09-02 20:29:14

我正在尝试存储对应用程序属性所做的更改。该文件位于包中,这与包含我的 UI 和模型的包不同。.propertiesresources

我使用以下命令打开了软件包:

this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")

是否有此功能等效项,允许我在同一个.属性文件?


答案 1

通常,您无法将内容放回从类加载器获取的资源中:

  • 类装入器资源通常是只读的。即保存在只读文件/只读目录中。

  • 如果从 JAR 文件获取资源,则 JAR 文件不是简单的可更新文件。(要“更新”,您需要提取旧JAR的内容,并使用更新的内容创建一个新的JAR。这一切都与ZIP文件的结构有关...)

  • 在某些情况下,类装入器资源将动态下载,并且无法将更改推送回下载位置。

即使您可以更新从类加载器获得的资源,这也是一个坏主意/坏做法。

  • 这样做会“污染”干净的应用程序安装与用户的首选项。除此之外,这意味着安装无法与其他用户共享(除非您处理多个用户的首选项...

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

  • 拥有特定于用户的应用程序副本存在管理问题。如果用户必须安装自己的应用程序副本,则也存在潜在的安全问题。

  • 在某些平台上,文件锁定或缓存可能存在技术问题,这些问题会妨碍(安全)更新,或者使应用程序难以在不重新启动的情况下加载更新的资源。

最后,这不是系统管理员(和受过良好教育的用户)期望软件的行为方式。Java 应用程序应该以预期的方式处理用户首选项:

  • 您可以使用 Java 首选项 API

  • 您可以将包含首选项的属性文件写入操作系统适当的用户可写目录。

  • 在 Windows 上,您可以使用特定于 Windows 的 API 将首选项存储在 Windows 注册表中,但这样做会使应用程序依赖于 Windows。(我看不出这样做有什么真正的好处,但我不是Window专家。


答案 2

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

getResourceAsStream()旨在打开用于阅读的资源,这些资源可以位于类路径上的任何位置。你不能写URL或JAR内部,你只能写文件,所以给你相同的输出API是没有意义的。

给自己找一个可以写入的目录,并在那里写入你的属性。

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