【JAVA Properties类概述】
一、概述。
之前说过,该对象是和IO流相结合的技术,所以和IO流结合在一起来讲比较合适。
public class Propertiesextends Hashtable<Object,Object> |
该类的继承层次:
java.lang.Object
|--java.util.Dictionnary<K,V>
|--java.util.Hashtable<Object,Object>
|--java.util.Properties
JDK1.6API对其描述:
Properties
类表示了一个持久的属性集。Properties
可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。
简单来说,Properties类的特点是:
1.该集合中的键和值都是字符串类型。
2.集合中的数据可以保存到流中或者从流中获取数据。
3.通常该集合用于操作以键值对形式存在的配置文件。
二、常用方法。
0.构造方法。
Properties() 创建一个无默认值的空属性列表。 |
Properties(Properties defaults)
创建一个带有指定默认值的空属性列表。 |
第一个方法无默认值,第二个方法则有一个参数,该参数是Properties类型的,实际上是将defaults中的键值对作为新创建的Properties对象的默认属性列表。但是,新创建的对象并不会改变原有defaults的内容(无论增删),这样可能就会出现一些怪现象。
1 private static void propertiesDemo01() { 2 Properties p=new Properties(); 3 p.setProperty("01", "zhangsan"); 4 p.setProperty("02", "lisi"); 5 p.setProperty("03", "wangwu"); 6 Properties pp=new Properties(p); 7 8 pp.remove("01"); 9 System.out.println(pp.getProperty("01")); 10 System.out.println(p.getProperty("01")); 11 12 p.remove("01"); 13 System.out.println(p.getProperty("01")); 14 System.out.println(pp.getProperty("01")); 15 }
该段代码的执行结果是:
1 zhangsan 2 zhangsan 3 null 4 null
可以看到,新建立的对象即使删除了defaults的键值对也仍然能够输出指定的信息,这是因为它的操作没有影响到defaults中的内容。但是查询则不一样,如果在当前属性列表中没有找到指定的键,则它会去默认属性列表中查找,如果没有才返回null。我们在这里可以发现,实际上defaults才是“幕后统治者”,新建立的对象无论增删改查都不会影响到它的内容,但是如果它自己增删改了某些内容,则会影响到新建立的对象。
1.添加、删除、修改、遍历、取值
【1】添加、删除、修改、取值
public String getProperty(String key)
|
public String getProperty(String key, String defaultValue)
|
public Object setProperty(String key,String value)
|
public V remove(Object key)
|
示例:
1 private static void propertiesDemo01() { 2 Properties p=new Properties(); 3 p.setProperty("01", "zhangsan"); 4 p.setProperty("02", "lisi"); 5 p.setProperty("03", "wangwu"); 6 7 p.remove("01"); 8 p.list(System.out); 9 System.out.println(p.getProperty("04")); 10 System.out.println(p.getProperty("04","赵六")); 11 }
【2】遍历
public Enumeration<?> propertyNames()
|
public Set<String> stringPropertyNames()
|
上面两个方法中,第一个方法是不常用的方法,因为该方法的返回值是枚举类型的,而枚举类型现在已经不推荐使用了。所以最常使用的方法就是第二种方法。
stringPropertyNames()方法中到底做了些什么呢?实际上它就是使用枚举类型遍历该集合,然后使用新建立的HashTable对象存储遍历的键值对,最后返回该HashTable对象的keySet方法的返回值。
但是我们应当还有另外一种思路:自定义遍历方法。使用Iterator迭代器遍历集合。
1 import java.util.Enumeration; 2 import java.util.Iterator; 3 import java.util.Properties; 4 import java.util.Set; 5 6 class IT implements Iterator<String>//自定义迭代器 7 { 8 Enumeration<String> en; 9 public IT(Enumeration enumeration) 10 { 11 this.en=enumeration; 12 } 13 @Override 14 public boolean hasNext() { 15 return en.hasMoreElements(); 16 } 17 18 @Override 19 public String next() { 20 return en.nextElement(); 21 } 22 } 23 public class PropertiesDemo { 24 25 public static void main(String[] args) { 26 propertiesDemo03(); 27 } 28 29 private static void propertiesDemo03() { 30 Properties p=new Properties(); 31 p.setProperty("01", "zhangsan"); 32 p.setProperty("02", "lisi"); 33 p.setProperty("03", "wangwu"); 34 IT it=new IT(p.propertyNames()); 35 while(it.hasNext()) 36 { 37 System.out.println(p.getProperty(it.next())); 38 } 39 }
但是我们还有另外一种更好的方式:使用Collections.list方法,可以将枚举类型转换为ArrayList集合。
1 private static void propertiesDemo04() { 2 Properties p=new Properties(); 3 p.setProperty("01", "zhangsan"); 4 p.setProperty("02", "lisi"); 5 p.setProperty("03", "wangwu"); 6 ArrayList<String>list=(ArrayList<String>) Collections.list(p.propertyNames()); 7 Iterator<String>it=list.iterator(); 8 while(it.hasNext()) 9 { 10 String str=it.next(); 11 System.out.println(str+"="+p.getProperty(str)); 12 } 13 }
当然这只是两种方法,当然还是它本身提供的stringPropertyNames方法最好。
1 private static void propertiesDemo05() { 2 Properties p=new Properties(); 3 p.setProperty("01", "zhangsan"); 4 p.setProperty("02", "lisi"); 5 p.setProperty("03", "wangwu"); 6 Set<String>set=p.stringPropertyNames(); 7 for(String key:set) 8 { 9 System.out.println(key+"="+p.getProperty(key)); 10 } 11 }
2.list方法。
void |
list(PrintStream out) 将属性列表输出到指定的输出流。 |
void |
list(PrintWriter out)
将属性列表输出到指定的输出流。 |
这两个方法对调试很有用,但是应当注意它不能对数据进行其它操作(只用于打印输出)。
我们可以使用
p.list(System.out);
将p中的键值对直接打印到屏幕。
同理,我们可以使用
System.getPropertis.list(System.out);
将本机的信息打印到屏幕上。
3.store方法。
void |
store(OutputStream out, String comments) 以适合使用 load(InputStream)
方法加载到 Properties 表中的格式,将此 Properties
表中的属性列表(键和元素对)写入输出流。 |
void |
store(Writer writer, String comments)
以适合使用 load(Reader)
方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。 |
这两个方法正是“Properties
可保存在流中”的体现,它将Properties对象和输出流(字节流和字符流)关联了起来,可以很方便的将数据保存到文件,实现“持久的属性集”。
使用此方法将键值对写入文件的时候,应当注意:不要使用中文,否则会出现乱码。配置文件中,#是注释符号。
private static void propertiesDemo06() throws IOException { Properties p=new Properties(); p.setProperty("01", "zhangsan"); p.setProperty("02", "lisi"); p.setProperty("03", "wangwu"); FileOutputStream fos=new FileOutputStream("ini.ini"); p.store(fos, "this is Properties information"); fos.close(); }
注意,使用完了流,store方法并不会关闭文件,所以要手动关闭才行。
1 #this is Properties information 2 #Fri Oct 24 11:36:48 CST 2014 3 03=wangwu 4 02=lisi 5 01=zhangsan
4.load方法。
void |
load(InputStream inStream) 从输入流中读取属性列表(键和元素对)。 |
void |
load(Reader reader)
按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 |
该方法正是“Properties
可从流中加载”的体现,它将Properties对象和输入流(字节流和字符流)关联了起来,可以很方便的将数据从文件加载到内存,实现对数据的增删改查操作。
比如:将wangwu的年龄改为30,需要各种方法配合使用才行。
原始文件内容:
1 zhangsan=23 2 lisi=24 3 wangwu=25 4 zhaoliu=26 5 chenqi=27 6 jianba=28
1 private static void propertiesDemo07() throws IOException { 2 Properties p=new Properties(); 3 InputStream is=new FileInputStream("ini.ini"); 4 p.load(is); 5 is.close(); 6 p.setProperty("wangwu","30"); 7 OutputStream os=new FileOutputStream("ini.ini"); 8 p.store(os, "this is properties information"); 9 os.close(); 10 }
1 #this is properties information 2 #Fri Oct 24 11:34:57 CST 2014 3 jianba=28 4 chenqi=27 5 zhangsan=23 6 lisi=24 7 zhaoliu=26 8 wangwu=30
注意,不要忘了关流,同时FileInputStream和FileOutputStream流不要紧挨在一起定义,否则初始文件会在FileOutputStream对象创建之后被清空。最后的结果只剩下一行。