【问题标题】:how to store java.util.prefs.Preferences in file?如何将 java.util.prefs.Preferences 存储在文件中?
【发布时间】:2012-05-01 00:25:46
【问题描述】:

我将 java.util.prefs.Preferences 用于应用程序首选项。 而且我需要手动编辑这些首选项的能力。 是否可以将其存储到文件而不是 Windows 注册表中? 或者我应该使用其他机制而不是 java.util.prefs.Preferences?

【问题讨论】:

标签: java configuration


【解决方案1】:

如果您想继续使用 Preferences API,但要写入文件,则需要一个新的 PreferencesFactory,详见 this SO post

【讨论】:

    【解决方案2】:

    您将要使用以下两种方法:

     Preferences.exportSubtree(OutputStream os) 
    

    Preferences.importPreferences(InputStream is)
    

    【讨论】:

    • 如果它对其他人有用,如果在 Android 中使用它,exportSubtree() 在三星设备上会失败(在 Lollipop 上测试),而 exportNode() 在所有手机上都有效。当然,如果要保存节点的所有后代,那么 exportNode() 将不起作用。
    【解决方案3】:

    这段代码应该可以帮助你[http://java.sun.com/developer/technicalArticles/releases/preferences/]:

    public class PrefSave {
    
    private static final String PACKAGE = "/pl/test";
    
    public static void main(String[] args) {
        doThings(Preferences.systemRoot().node(PACKAGE));
        doThings(Preferences.userRoot().node(PACKAGE));
    }
    
    public static void doThings(Preferences prefs) {
        prefs.putBoolean("Key0", false);
        prefs.put("Key1", "Value1");
        prefs.putInt("Key2", 2);
    
        Preferences grandparentPrefs = prefs.parent().parent();
        grandparentPrefs.putDouble("ParentKey0", Math.E);
        grandparentPrefs.putFloat("ParentKey1", (float) Math.PI);
        grandparentPrefs.putLong("ParentKey2", Long.MAX_VALUE);
    
        String fileNamePrefix = "System";
        if (prefs.isUserNode()) {
            fileNamePrefix = "User";
        }
        try {
            OutputStream osTree = new BufferedOutputStream(
                    new FileOutputStream(fileNamePrefix + "Tree.xml"));
            grandparentPrefs.exportSubtree(osTree);
            osTree.close();
    
            OutputStream osNode = new BufferedOutputStream(
                    new FileOutputStream(fileNamePrefix + "Node.xml"));
            grandparentPrefs.exportNode(osNode);
            osNode.close();
        } catch (IOException ioEx) {
            // ignore
        } catch (BackingStoreException bsEx) {
            // ignore too
        }
    }
    

    【讨论】:

      【解决方案4】:

      尝试以下类,它允许您使用本地 configuration.xml 文件使用一些简单的 put()get() 函数。

      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.util.InvalidPropertiesFormatException;
      import java.util.Properties;
      
      public class SimpleProperties
      {
          private String propertiesFilePath;
          private Properties properties;
      
          public SimpleProperties() throws InvalidPropertiesFormatException, IOException
          {
              propertiesFilePath = "configuration.xml";
              properties = new Properties();
      
              try
              {
                  properties.loadFromXML(new FileInputStream(propertiesFilePath));
              } catch (InvalidPropertiesFormatException e)
              {
      
              }
          }
      
          public void put(String key, String value) throws FileNotFoundException, IOException
          {
              properties.setProperty(key, value);
      
              store();
          }
      
          public String get(String key)
          {
              return properties.getProperty(key);
          }
      
          private void store() throws FileNotFoundException, IOException
          {
              String commentText = "Program parameters";
      
              properties.storeToXML(new FileOutputStream(propertiesFilePath), commentText);
          }
      }
      

      【讨论】:

        【解决方案5】:

        在另一篇博文中有解释,here

        Properties prop = new Properties();
        InputStream in = getClass().getResourceAsStream("foo.properties");
        prop.load(in);
        in.close()
        

        【讨论】:

        • 抱歉 - 不一样。 Comparing Preferences API to Other Mechanisms。在 Windows 中,有两个地方可以放置首选项。注册表或 %APPDATA%。 F.e.在 QSettings(Qt 框架)中,我可以在这两个选项之间进行选择...
        • 对不起,我误会了。那个怎么样?我无法测试,但似乎您正在寻找什么。 davidc.net/programming/java/…
        • 好多了。谢谢你,@MEK。
        【解决方案6】:

        我认为您可以改用属性文件。它们存储在文件系统中。你可以定义你想要的路径。您可以手动编辑它。详情请见this question

        【讨论】:

          【解决方案7】:

          不久前,我不得不想出一个 Preferences 类的实现,它可以从注册表读取设置但不写入注册表。我从 AbstractPreferences 派生了一个 ReadOnlyPreferences 类来完成此任务。后来,我需要与访问/从文件完全相同的功能。我刚刚扩展了我的 ReadOnlyPreferences 类以覆盖 sync() 和 flush() 以保持文件同步。关于这一点很酷的部分,它将使用完全相同的逻辑将默认值应用于值,就像通常使用首选项一样,因为注册表中实际上没有任何内容可供读取。我使用基类中的 exportSubtree() 和 importPreferences() 使文件保持同步,为我完成所有繁重的工作。

          很抱歉,我无法发布代码,因为我不拥有它,但我使用了您可以在以下链接中找到的加密首选项作为起点。这就是我所做的,我花了大约一个小时将它提炼成我需要的东西,主要是扔掉代码,这比编写代码容易得多!如果您不想单击第一个,它也发布在 Dobbs 博士的以下链接中。我只是从来没有在 dobbs 文章上看到一个简单的地方来下载整个源代码。无论如何,这篇文章是我见过的关于扩展偏好内容的最佳文章。

          http://www.panix.com/~mito/articles/#ep

          http://www.drdobbs.com/security/encrypted-preferences-in-java/184416587?pgno=4

          【讨论】:

            猜你喜欢
            • 2019-05-22
            • 2012-06-07
            • 2010-10-06
            • 1970-01-01
            • 2013-12-23
            • 1970-01-01
            • 2013-11-02
            • 2019-11-24
            • 2021-01-17
            相关资源
            最近更新 更多