疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java读写Properties属性文件


 

        Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

  一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。

  因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。

  Properties属性文件在JAVA应用程序中是经常可以看得见的,也是特别重要的一类文件。它用来配置应用程序的一些信息,不过这些信息一般都是比较少的数据,没有必要使用数据库文件来保存,而使用一般的文本文件来保存,如果是通过File直接保存的话,可能在存储和读取上都不是很方便,但如果保存为Properties文件就不一样了,属性文件都有键值对应的,在JAVA的包中,有提供专门的操作属性文件的类。这个类就是 java.uitl.Properties类,由于Properties类是一个集合类,所以,Properties会将属性以集合的方式读写。

  注意:下面的代码中对于抛出的异常都未采取捕获的方式,自己在编写程序的时候一定要注意捕获异常,推荐将捕获的异常处理掉。

  Properties类继承字Hashtable类,采用键值对应的存储方式,在使用Properties类管理属性文件时有什么方便的呢?Properties类有专门的读写方法来读写Properties属性文件,不用担心读写的格式问题,只要为Properties类提供一个读写流即可。Properties用于读写属性文件的方法分别是:

  Java代码

  //读取属性文件流的方法

  public void load(InputStream inStream) throws IOException {}

  //写属性文件流的方法

  public void store(OutputStream out, String comments) throws IOException {}

  首先,我们来看看如何从一个属性文件中读取属性。

  假定我们已经新建了一个属性文件,名为prop.properties,内容如下:

  Java代码

  sitename=abcjava

  siteurl=www.abcjava.com

  我们要做的第一步就是要将文件读取到Properties类对象中,由于load有一个参数是InputStream,所以我们可以用 InputStream的子类FileInputStream将属性文件读取到Properties对象中,知道prop.properties的路径,我们就用FileInputStream(String name)构造

  函数:

  Java代码

  Properties prop = new Properties();//属性集合对象

  FileInputStream fis = new FileInputStream("prop.properties");//属性文件流

  prop.load(fis);//将属性文件流装载到Properties对象中

  接下来我们将做的事情就是如果读取一个属性,因为属性文件中的每一行都是一个键值对应,所以每一行都代表了一个属性对象,每一行都将以键和值的关系存储到Properties中,Properties类提供了getProperty(String key)方法用来通过键名读取键值,当key在属性集合中找不到时又想为key在程序中赋予一个值时可以使用public String getProperty(String key,String defaultValue)方法,这个方法的意思就是用指定的键在属性列表中搜索属性。如果在属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回默认值变量:

  Java代码

  //获取属性值,sitename已在文件中定义

  System.out.println("获取属性值:sitename=" + prop.getProperty("sitename"));

  //获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件

  System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));

  在知道怎么读取属性文件之后我们还有一个很重要的事情就是要修改和添加新的属性到属性文件,这里就是使用public void store(OutputStream out, String comments)方法,这个方法是将属性集合写到一个OutputStream流中,同InputStream流一样,这里同样是使用其子类FileOutputStream(String name),这里就不多说了。

  在保存属性集合到文件之前,我们还有一件事情就是如何修改和添加新的属性到属性集合,这里使用了一个方法就是setProperty(String key, String value),这个方法就是当属性集合中存在指定的key时,就修改这个key的值,如果不存在,就新建一个key,同样是通过键值关系保存的,但值得注意的是,Properties类继承自Hashtable,所以也可以用Hashtable的put和putAll方法保存,但强烈反对使用这两个方法,因为它们允许调用方插入其键或值不是 Strings 的项。相反,应该使用 setProperty 方法。如果在“有危险”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。那好,下面我们就来看看修改、添加和保存属性的程序:

  //修改sitename的属性值

  prop.setProperty("sitename", "Boxcode");

  //添加一个新的属性studio

  prop.setProperty("studio", "Boxcode Studio");

  //文件输出流

  FileOutputStream fos = new FileOutputStream("prop.properties");

  //将Properties集合保存到流中

  prop.store(fos, "Copyright (c) Boxcode Studio");

  fos.close();//关闭流

  接下就是整个程序的源代码:

  Java代码

  import java.io.FileInputStream;

  import java.io.FileOutputStream;

  import java.util.Properties;

  public class PropertyEditor {

  public static void main(String[] args) throws Exception {

  Properties prop = new Properties();// 属性集合对象

  FileInputStream fis = new FileInputStream("prop.properties");// 属性文件输入流

  prop.load(fis);// 将属性文件流装载到Properties对象中

  fis.close();// 关闭流

  // 获取属性值,sitename已在文件中定义

  System.out.println("获取属性值:sitename=" + prop.getProperty("sitename"));

  // 获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件

  System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));

  // 修改sitename的属性值

  prop.setProperty("sitename", "Boxcode");

  // 添加一个新的属性studio

  prop.setProperty("studio", "Boxcode Studio");

  // 文件输出流

  FileOutputStream fos = new FileOutputStream("prop.properties");

  // 将Properties集合保存到流中

  prop.store(fos, "Copyright (c) Boxcode Studio");

  fos.close();// 关闭流

  }

  }

  在我们知道如何读写一个属性文件之后,我们仍然还有很多需要注意的问题,因为load和store方法都是按照ISO-8859-1的编码方式读写属性流文件的,而ILatin1 的字符和某些特殊字符,而对于非Latin1 的字符和某些特殊字符,则要使用与字符和字符串字面值所用的类似转义序列,以值和元素的形式来表示它们。所以当我们在处理中文时,不可以在直接修改属性文件时,将中文的值赋予给属性,而是要在JAVA程序中通过setProperty方法给属性赋予中文的值,因为这样store会将中文转换成 unicode码,在读取时系统会将读取到的unicode码按系统的编码打印出来,对于中文系统,通常是GBK码,这样中文才能够正常显示。

  方法摘要

  String getProperty(String key)

  用指定的键在此属性列表中搜索属性。

  String getProperty(String key, String defaultValue)

  用指定的键在属性列表中搜索属性。

  void list(PrintStream out)

  将属性列表输出到指定的输出流。

  void list(PrintWriter out)

  将属性列表输出到指定的输出流。

  void load(InputStream inStream)

  从输入流中读取属性列表(键和元素对)。

  void load(Reader reader)

  按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。

  void loadFromXML(InputStream in)

  将指定输入流中由 XML 文档所表示的所有属性加载到此属性表中。

  Enumeration propertyNames()

  返回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键。

  void save(OutputStream out, String comments)

  已过时。 如果在保存属性列表时发生 I/O 错误,则此方法不抛出 IOException。保存属性列表的首选方法是通过 store(OutputStream out, String comments) 方法或 storeToXML(OutputStream os, String comment) 方法来进行。

  Object setProperty(String key, String value)

  调用 Hashtable 的方法 put。

  void store(OutputStream out, String comments)

  以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。

  void store(Writer writer, String comments)

  以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。

  void storeToXML(OutputStream os, String comment)

  发出一个表示此表中包含的所有属性的 XML 文档。

  void storeToXML(OutputStream os, String comment, String encoding)

  使用指定的编码发出一个表示此表中包含的所有属性的 XML 文档。

  Set stringPropertyNames()

  返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。

  Properties props=System.getProperties(); //系统属性

  System.out.println("Java的运行环境版本:"+props.getProperty("java.version"));

  System.out.println("Java的运行环境供应商:"+props.getProperty("java.vendor"));

  System.out.println("Java供应商的URL:"+props.getProperty("java.vendor.url"));

  System.out.println("Java的安装路径:"+props.getProperty("java.home"));

  System.out.println("Java的虚拟机规范版本:"+props.getProperty("java.vm.specification.version"));

  System.out.println("Java的虚拟机规范供应商:"+props.getProperty("java.vm.specification.vendor"));

  System.out.println("Java的虚拟机规范名称:"+props.getProperty("java.vm.specification.name"));

  System.out.println("Java的虚拟机实现版本:"+props.getProperty("java.vm.version"));

  System.out.println("Java的虚拟机实现供应商:"+props.getProperty("java.vm.vendor"));

  System.out.println("Java的虚拟机实现名称:"+props.getProperty("java.vm.name"));

  System.out.println("Java运行时环境规范版本:"+props.getProperty("java.specification.version"));

  System.out.println("Java运行时环境规范供应商:"+props.getProperty("java.specification.vender"));

  System.out.println("Java运行时环境规范名称:"+props.getProperty("java.specification.name"));

  System.out.println("Java的类格式版本号:"+props.getProperty("java.class.version"));

  System.out.println("Java的类路径:"+props.getProperty("java.class.path"));

  System.out.println("加载库时搜索的路径列表:"+props.getProperty("java.library.path"));

  System.out.println("默认的临时文件路径:"+props.getProperty("java.io.tmpdir"));

  System.out.println("一个或多个扩展目录的路径:"+props.getProperty("java.ext.dirs"));

  System.out.println("操作系统的名称:"+props.getProperty("os.name"));

  System.out.println("操作系统的构架:"+props.getProperty("os.arch"));

  System.out.println("操作系统的版本:"+props.getProperty("os.version"));

  System.out.println("文件分隔符:"+props.getProperty("file.separator")); //在 unix 系统中是"/"

  System.out.println("路径分隔符:"+props.getProperty("path.separator")); //在 unix 系统中是":"

  System.out.println("行分隔符:"+props.getProperty("line.separator")); //在 unix 系统中是"/n"

  System.out.println("用户的账户名称:"+props.getProperty("user.name"));

  System.out.println("用户的主目录:"+props.getProperty("user.home"));

  System.out.println("用户的当前工作目录:"+props.getProperty("user.dir"));