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

问题描述 投票:15回答:5

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

我使用以下方法打开了包装:

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

是否有与之等效的功能,可让我将对Properties类的更改持久保存在同一.Properties文件中?

java swing file-io properties persistence
5个回答
2
投票

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


25
投票

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

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

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

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

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

  • 这样做会根据用户的偏好“污染”干净的应用程序安装。除其他外,这意味着安装不能与其他用户共享(除非您处理多个用户的首选项...)。

  • 将应用程序安装为可写状态存在安全问题,因此可以更新嵌入式首选项。考虑病毒!考虑一个可能会破坏另一个用户偏好的用户!

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

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

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

  • 您可以使用Java Preferences API

  • 您可以write a Properties file包含对操作系统合适的用户可写目录的首选项。

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


9
投票

在'resources'程序包中,与包含我的UI和模型的程序包是different

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

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

是否有与之等效的功能,允许我将对Properties类的更改持久保存在同一.Properties文件中?

您需要此Properties#store(),它可以使用Properties#store()OutputStream。首先,您需要获取属性文件的OutputStream并获取其Writer,以便为此创建一个Writer,然后将其包装在URL中。

URL

5
投票

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

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

找到一个您可以写入的目录,并在其中写入属性。

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


0
投票

除了URI,如果您打算频繁读写该文件,并且希望您的应用程序范围扩大,请考虑是否要进一步(或多步)使用文件-基于数据库File。有一些用于SQLite的JDBC包装器,可以使您超越Java属性接口提供的基本字符串键值查找。

© www.soinside.com 2019 - 2024. All rights reserved.