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

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

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

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

是否有一个function相当的允许我在同一.Properties文件中持久更改属性类?

听起来您想要存储用户首选项。 考虑使用Java Preferences API 。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); properties.load(classLoader.getResourceAsStream("resources/settings.properties")); 

是否有一个function相当的允许我在同一.Properties文件中持久更改属性类?

您需要Properties#store() ,可以使用OutputStreamWriter 。 首先,您需要获取属性文件的URL并获取其URI以便您可以为FileOutputStream创建一个File

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

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

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

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

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

除了Carl的回答之外 ,如果您要经常读取和写入此文件,并期望您的应用程序扩展范围,请考虑是否进一步(或几个步骤)进一步使用基于文件的数据库,如SQLite 。 SQLite有一些JDBC包装器可以让您超越Java Properties接口提供的基本字符串键值查找。