Properties提供的应用程序解决方案主要存在两个问题:
(1)配置文件不能放在主目录中,因为某些OS(如Win9X)没有主目录的概念;
(2)没有标准的文件命名规则,存在文件名冲突的可能性。
Java中的Preferences类可以解决这些问题。Preferences提供一个存储配置信息的中心知识库,与平台无关。在Windows系统中,它存储在注册表中,在Linux中存储在本地文件系统中。它的实现是透明的,程序员无需深究它的底层是如何实现的。
Preferences的中心知识库是树状结构,因此可以避免文件名冲突。每个用户都有一棵树,存放与本用户有关的配置;还有一个系统树,存放全体用户的公共信息。内部的配置信息仍然以key-value的结构进行存储。
Preferences的使用步骤如下:
(1)获得根节点
Preferences root = Preferences.userRoot();
Preferences root = Preferences.systemRoot();
如果配置信息位于用户树,则获取用户树的根节点,否则获取系统树根节点;
(2)获取配置节点
preferences = root.node("path");
path是配置节点相对于根节点的路径;
如果节点的路径名与类的包名相同,则可通过类的对象直接获得配置节点:
Preferences node = Preferences.userNodeForPackage(this.getClass());
Preferences node = Preferences.systemNodeForPackage(this.getClass());
(3)读取配置项
String title = preferences.get("title", "default title");
Preferences要求读取配置项时必须指定默认值。因为在实际环境中总会有各种不如意,比如系统中还没有中心知识库,或者网络暂时不可用等等。
(4)设置配置项
preferences.put(key, value);
(5)同步配置项
preferences.flush();
flush()方法用于立即将配置项写入到文件中。
下面是Preferences类中的常用方法:
示例代码如下:
PreferencesDemo.java
package ConfigByPreferencesDemo; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.prefs.BackingStoreException; import java.util.prefs.InvalidPreferencesFormatException; import java.util.prefs.Preferences; import javax.swing.*; /* * 功能:演示Preferences的用法,实现JFrame窗体参数的修改、保存以及导入导出到xml文件中。 * 版本:20150807 * 结构:PreferencesDemo[主窗体],PreferencesDialog */ public class PreferencesDemo extends JFrame { private Preferences preferences;//配置内容 public PreferencesDemo() { // 加载配置 loadPreferences(); // 设置窗体属性 initFrame(); } public void loadPreferences() { /* * 加载配置,它位于注册表 */ Preferences root = Preferences.userRoot();//HKEY_CURRENT_USER\Software\JavaSoft\Prefs preferences = root.node("/com/horstmann/corejava"); } public void updatePreferencesValue(String key, String value){ /* * 功能:更新Preferences的内容 */ preferences.put(key, value); } public void flushPreferences() { /* * 功能:将最新Preferences的值写入配置文件 */ try { preferences.flush(); } catch (BackingStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String getPreferencesValue(String key){ /* * 功能:根据key获取configProperties中对应的value */ return preferences.get(key, "0"); } public void exportPreferences(OutputStream out) { /* * 导出配置 */ try { preferences.exportSubtree(out); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BackingStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void importPreferences(InputStream in) { /* * 导入配置 */ try { Preferences.importPreferences(in); in.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (InvalidPreferencesFormatException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } public void initFrame() { //获取参数,如果不存在则取默认值 String left = preferences.get("left", "0"); String top = preferences.get("top", "0"); String width = preferences.get("width", "300"); String height = preferences.get("height", "200"); String title = preferences.get("title", "default title"); JMenuBar menubar = new JMenuBar(); JMenu windowMenu = new JMenu("Window"); windowMenu.setMnemonic('W'); JMenuItem preferencesItem = new JMenuItem("Preferences"); preferencesItem.setMnemonic('P'); preferencesItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub PreferencesDialog optionsDialog = new PreferencesDialog(PreferencesDemo.this); optionsDialog.setVisible(true); } }); setJMenuBar(menubar); menubar.add(windowMenu); windowMenu.add(preferencesItem); setBounds(Integer.parseInt(left), Integer.parseInt(top), Integer.parseInt(width), Integer.parseInt(height)); setTitle(title); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main(String[] args) { // TODO Auto-generated method stub PreferencesDemo preferencesDemo = new PreferencesDemo(); preferencesDemo.setVisible(true); } }
PreferencesDialog.java