【问题标题】:Java OutputStream equivalent to getClass().getClassLoader().getResourceAsStream()Java OutputStream 等价于 getClass().getClassLoader().getResourceAsStream()
【发布时间】:2010-01-08 22:33:46
【问题描述】:

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

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

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

是否有与此功能等效的功能允许我在同一个 .Properties 文件中保留对 Properties 类的更改?

【问题讨论】:

    标签: java swing file-io properties persistence


    【解决方案1】:

    一般来说,您不能将东西放回从类加载器获得的资源中:

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

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

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

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

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

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

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

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

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

    • 您可以使用Java Preferences API

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

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

    【讨论】:

      【解决方案2】:

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

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

      为自己找到一个允许写入的目录,并在那里写入你的属性。

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

      【讨论】:

        【解决方案3】:

        听起来您想存储用户偏好。考虑为此使用Java Preferences API

        【讨论】:

        • 如何选择这个答案?它建议以另一种方式做,而不是回答这个问题。即使另一种方法更好,它也没有回答最初的问题。您应该做的是回答所询问的内容,然后提出替代方法。
        • @FukuzawaYukio:在这种情况下,解决问题而不是回答问题更有用。请注意,答案是由提出问题的人选择的,所以看起来他们也是这么认为的。
        【解决方案4】:

        除了Carl's answer之外,如果你要经常读写这个文件,并期望你的应用程序的范围会扩大,考虑是否进一步走一步(或多步)并使用一个文件- 基于数据库,如SQLite。有一些 SQLite 的 JDBC 包装器可以让您超越 Java Properties 接口提供的基本字符串键值查找。

        【讨论】:

          【解决方案5】:

          虽然将文件写入资源并不实用,但当我们的应用程序只在IDEA本地运行而没有部署时,我们仍然需要这样做,那么我们可以这样做:

          URL resource = Thread.currentThread().getContextClassLoader().getResource("settings.properties");
          String path= resource.getPath();
          OutputStream outputStream = new FileOutputStream(path);
          //outputStream write
          

          【讨论】:

            猜你喜欢
            • 2016-02-10
            • 2010-11-22
            • 2010-10-03
            • 1970-01-01
            • 2021-01-09
            • 2017-08-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多