1. 基础介绍
Properties是一个文件配置集合类,但是它常常用来加载一些配置文件因此也经常和IO流混在一起使用。
-
Properties类继承了Hashtable<Object,Object>类,并且内部存取键值对也是用的HashTable实现的,也是一个线程安全的类。
-
实现Serializable接口,虽然实现了序列化接口但是它的key - value方法都只是支持String -> String的一个键值对,可能实现序列化接口的用途在于使用序列化版本号来做唯一标识;
-
实现Cloneable接口所以构造方法是可以传入一个已经存在的Properties实例化对象来构造的。
-
实现了Map < Object , Object >可以对Properties实例化对象的集合元素进行遍历。
-
不仅只有下面的方法,由于继承了父类Hashtable,表面上虽然没有删除键值对的方法,其实是可以使用调用父类Hashtable的方法都能用。
2. 基本添加数据与三种遍历。
-
基本添加数据
import java.util.Properties; public class Main { public static void main(String[] args) { //1. 创建对象 Properties pro = new Properties(); //2. 设置Key - value pro.setProperty("name","wanglaowu"); pro.setProperty("age","20"); pro.setProperty("age","65"); //覆盖已经存在的值 pro.setProperty("height","180.2"); pro.remove("height"); //移除height属性 System.out.println(pro.toString()); } }
-
三种基础遍历方法
//3.1 使用KeySet遍历 Set<Object> keySet = pro.keySet(); //先获取map集合的所有键的Set集合 Iterator<Object> it = keySet.iterator();//有了Set集合,就可以获取其迭代器。 while(it.hasNext()){ String key = (String)it.next(); String value = pro.getProperty(key); System.out.println(key + " -> " + value); } //3.2 使用entrySet遍历 for (Map.Entry<Object, Object> entry : pro.entrySet()) { System.out.println(entry.getKey() + " -> " + entry.getValue()); } //3.3 使用stringPropertyNames遍历 Set<String> strings = pro.stringPropertyNames(); for(String key : strings){ System.out.println(key + " -> " + pro.getProperty(key)); }
3. 加载与输出
-
对于properties.list方法必须传入打印流,可以是PrintStream 也可以是 PrintWriter,建议采用PrintWriter打印流,并且设置字符编码集。出现乱码的几率会大大降低。
import java.io.PrintWriter; import java.util.Properties; public class Demo02 { public static void main(String[] args) { Properties pro = new Properties(); pro.setProperty("name","王老五"); pro.setProperty("age","20"); try { PrintWriter pw = new PrintWriter("file.txt", "UTF-8"); pro.list(pw); pw.close(); //一定要flush刷新,或者直接关闭也会调用flush } catch (Exception e) { e.printStackTrace(); } } }
注意:采用编码的PrintWriter类再使用完流之后一定要关闭,切记不要将带指定编码的PrintWriter的实例化直接写入list()里,文件中将会没有数据。因为带指定编码的PrintWriter是建立在一个缓冲流 -> 字节转换流 -> 文件流三个流的基础上。由于缓冲流的缓冲区较大,直接将实例化作为对象写入完毕后数据全在缓冲区,并没有对这个流进行刷新或者关闭。
-
load方法可以加载一个.properties后缀文件,store方法可以导出为一个.properties后缀文件。这两个方法都支持字符流或者字节流,还是建议字符流并且选择支持设置编码格式的字符流,注意文件乱码问题。
import java.io.*; import java.util.Properties; public class Demo03 { public static void storeOp(){ Properties pro = new Properties(); pro.setProperty("Hello","好好学习"); pro.setProperty("World","天天向上"); try{ OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream("file.properties"), "UTF-8"); pro.store(osw,"这是注释"); osw.close(); }catch (Exception e){ e.printStackTrace(); } } public static void loadOp(){ Properties pro = new Properties(); try { InputStreamReader isr = new InputStreamReader( new FileInputStream("file.properties"),"utf-8"); pro.load(isr); pro.list(System.out); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { storeOp(); loadOp(); } }
-
loadToXML加载一个.XML配置文件,storeToXML导出为一个.XML配置文件。这两个方法都只支持字节流,但是storeToXML方法可以设置字符编码集,不设置默认是utf8格式。
import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; public class Demo04 { public static void storeXML(){ Properties pro = new Properties(); pro.setProperty("store","好好学习"); pro.setProperty("load","天天向上"); try{ FileOutputStream fos = new FileOutputStream("file.xml"); pro.storeToXML(fos,"这是注释","UTF-8"); fos.close(); }catch (Exception e){ e.printStackTrace(); } } public static void loadXML(){ Properties pro = new Properties(); try{ FileInputStream fis = new FileInputStream("file.xml"); pro.loadFromXML(fis); pro.list(System.out); fis.close(); }catch (Exception e){ e.printStackTrace(); } } public static void main(String[] args) { storeXML(); loadXML(); } }