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()
,可以使用OutputStream
或Writer
。 首先,您需要获取属性文件的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接口提供的基本字符串键值查找。