缘起
因为项目的需要,最近在研究JPF(Java PathFinder)。JPF是有NASA提供一款模型检查工具,其核心jpf-core是实际就是一个JVM,可以通过JPF的配置机制来方便的实现功能的配置和扩展。JPF的扩展机制是基于java.util.properties类的。因此在网上搜集了一番。
简介
Properties属性文件在JAVA应用程序很常见,也是特别重要的一类文件。它用来存储一些配置应用程序信息,并且此类信息数据量少并使用文本文件而不是数据库文件来来存储。如果是通过File类直接保存的,在存储和读取上都不是很方便(需要自己写解析和存储的方法)。而如果存为Properties(属性)文件(存储格式为键值对),就可以使用java.uitl.Properties类来操作。Properties类是一个集合类,它继承自Hashtable类,采用键值对应的存储方式,并且以集合的方式读写属性。properties文件的键值对形式如下,其键和值是用等号分隔的:
jdk_home=/usr/lib/jvm/jdk
foo=test
J2SE 1.5 以前的版本要求直接使用 XML 解析器来装载配置文件并存储设置。虽然这并非是一件困难的事情,并且解析器是平台的标准部分,但是额外的工作总是有点让人烦。新的JDK中的 java.util.Properties 类现在提供了一种为程序装载和存储设置的更容易的方法: loadFromXML(InputStream is) 和 storeToXML(OutputStream os, String comment) 方法。
java读取properties文件
1.使用java.util.Properties类的load()方法
示例:
InputStream in = lnew BufferedInputStream(new FileInputStream(name));
Properties p = new Properties();
p.load(in);
2.使用java.util.ResourceBundle类的getBundle()方法示例:
ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());
3.使用java.util.PropertyResourceBundle类的构造函数示例:
InputStream in = new BufferedInputStream(new FileInputStream(name));
ResourceBundle rb = new PropertyResourceBundle(in);
4.使用class变量的getResourceAsStream()方法示例:
InputStream in = JProperties.class.getResourceAsStream(name);
Properties p = new Properties();
p.load(in);
5.使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法示例:
InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);
Properties p = new Properties();
p.load(in);
6.使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法示例:
InputStream in = ClassLoader.getSystemResourceAsStream(name);
Properties p = new Properties();
p.load(in);
文本格式的属性文件
1.sample.properties属性文件示例
foo=bar
fu=baz
将sample.properties属性文件使用前面描述的方法装载到 Properties 对象中后,就可以找到两个键( foo 和 fu )和两个值( foo 的 bar 和 fu 的 baz )了。properties类支持带 \u 的嵌入 Unicode 字符串,并且将每一项内容都当作 String 。
2.LoadSample.java --读写properties文件
import java.util.*;
import java.io.*;
public class LoadSample {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
FileInputStream fis =
new FileInputStream("sample.properties");
prop.load(fis);
prop.list(System.out);
System.out.println("\nThe foo property: " +
prop.getProperty("foo"));
}
}
上述代码显示了如何装载属性文件并列出它当前的一组键和值。只需传递这个文件的 InputStream 给 load() 方法,就会将每一个键-值对添加到 Properties 实例中。然后用 list() 列出所有属性或者用 getProperty() 获取单独的属性。
3 编译&运行
编译LoadSample: javac LoadSample
运行LoadSample: java LoadSample (使用命令行的原因是程序太简单,没有必要建立工程来处理)
运行结果:
-- listing properties --
fu=baz
foo=bar
The foo property: bar
注意: list() 方法的输出中键-值对的顺序与它们在输入文件中的顺序不一样。这是因为 Properties 类在一个散列表(hashtable,事实上是一个 Hashtable 子类)中储存一组键-值对,所以不能保证顺序。 XML 格式的属性文件
下面演示从XML的格式的属性文件中读取数据,使用XML就必须要了解一下DTD(Document Type Definition)1.DTD的格式:
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD for properties -->
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>
上述XML DTD表示在外围 <properties> 标签中包装的是一个 <comment> 标签,后面是任意数量的 <entry> 标签。对每一个 <entry> 标签,有一个键属性,输入的内容就是它的值。下面展示了符合上述DTD的XML格式的属性文件。
2.XML的属性文件-sampleprops.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Hi</comment>
<entry key="foo">bar</entry>
<entry key="fu">baz</entry>
</properties>
3.读写XML的属性文件
import java.util.*;
import java.io.*;
public class LoadSampleXML {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
FileInputStream fis =
new FileInputStream("sampleprops.xml");
prop.loadFromXML(fis);
prop.list(System.out);
System.out.println("\nThe foo property: " +
prop.getProperty("foo"));
}
}
4 .编译&运行
编译: javac LoadSampleXML.java
运行: java LoadSampleXML
运行结果和上面的一样:
-- listing properties --
fu=baz
foo=bar
The foo property: bar
关于资源绑定的说明
java.util.Properties 类除了支持键-值对,还支持属性文件作为 XML 文件,不幸的是,没有内置的选项可以将 ResourceBundle 作为一个 XML 文件处理。PropertyResourceBundle 使用 Properties 对象来装载绑定,不过装载方法的使用是硬编码到类中的,而不使用较新的 loadFromXML() 方法。
保存 XML 属性
Properties类还可以将属性存储到 XML 格式的文件中。虽然 store() 方法仍然会创建一个类似sample.properties 所示的文件,但是现在可以用新的 storeToXML() 方法创建如 sampleprops.xml所示的文件。只要传递一个 OutputStream 和一个用于注释的 String 就可以了。下面代码展示了新的 storeToXML() 方法。
import java.util.*;
import java.io.*;
public class StoreXML {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
prop.setProperty("one-two", "buckle my shoe");
prop.setProperty("three-four", "shut the door");
prop.setProperty("five-six", "pick up sticks");
prop.setProperty("seven-eight", "lay them straight");
prop.setProperty("nine-ten", "a big, fat hen");
FileOutputStream fos =
new FileOutputStream("rhyme.xml");
prop.storeToXML(fos, "Rhyme");
fos.close();
}
}
编译运行后结果输出的rhyme.xml如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Rhyme</comment>
<entry key="seven-eight">lay them straight</entry>
<entry key="five-six">pick up sticks</entry>
<entry key="nine-ten">a big, fat hen</entry>
<entry key="three-four">shut the door</entry>
<entry key="one-two">buckle my shoe</entry>
</properties>
XML or 文本格式
使用 XML 文件还是使用老式的 a=b 类型的文件取决与个人喜好。老式文件从内存的角度看肯定是轻量级的。不过,由于 XML 的普遍使用以及相应的XML工具的成熟,XML 格式将会流行起来,因为它已经被广泛使用了(作为远程数据交换的通用格式),只不过没有用到 Properties 对象。分析软件包 private XMLUtils 类的源代码以获得关于所使用的 XML 解析的更多信息。
小结
搜索引擎和互联网改变了我们获取知识的方法。在传统的教育中,我们获取知识的来源只有书本(教科书或者是参考书或者图书馆的资料),现在搜索引擎作为整个互联网的索引,我们只要简单搜索一下,就可以获取以前花费很长时间才能找到的资料了。就在我写这篇博客之前,我对properties文件不太了解,google了几篇博文后,有了一个整体性的感触。由于相应的文章比较凌乱,我就稍作修整,使之更加的结构化。
搜索引擎无疑使我们更加容易的获取知识,但是正如《世界是平》中所言,在未来的社会中,如何分析加工处理信息,如何透过现象看到本质,如何区分知识和智慧,这一些都会成为新的挑战。如何面对这些挑战?我觉得持续不断的学习和思考,勇于面对新问题和挑战,做到扬长避短是面对挑战的策略和方法。无论如何要记住:机遇与挑战并存。
参考资料
[1] 使用JAVA读写Properties属性文件http://fluagen.blog.51cto.com/146595/409262
[2] java.util.Properties类的使用:http://gimgen1026.iteye.com/blog/152023
[3] java 读取properties文件的六种方法http://blog.csdn.net/senton/article/details/4083127