java IO流之属性集Properties【八】

1.概述

java.util.Properties 继承于 Hashtable,用来表示一个持久的属性集合

Properties集合是唯一一个和IO流相结合的集合,可以保存在IO流中,也可以从IO流中加载。

  • 使用store()方法,可以把集合中的临时数据,持久化存储到硬盘中。
  • 使用load()方法,可以把硬盘中的文件,读取到集合中使用。

Properties集合是一个双列集合,使用键值结构存储数据,key和value默认都是字符串,且Key唯一

该类被许多Java类使用,比如获取系统属性。

System.getProperties() 方法就是返回一个Properties对象。

2.构造方法:

public Properties() : 创建一个无默认值的空属性集列表。该方法等同于 Properties(null) 
public Properties(Properties defaults) : 创建一个带有指定默认值的空属性列表。 

2.1构造方法源码:

	// 默认属性集
	protected Properties defaults;
	
	public Properties() {
        this(null);
    }
    public Properties(Properties defaults) {
        this.defaults = defaults;
    }

3.存储和获取方法:

public Object setProperty(String key, String value) : 保存一对属性,底层调用 Hashtable 的 put方法 。

public String getProperty(String key) :根据key获取value。
public String getProperty(String key, String defaultValue)。根据key获取value,如果没找到,就返回defaultValue。

public Enumeration<?> propertyNames() :返回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键。 
public Set<String> stringPropertyNames() :返回此属性列表中的键集。如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。

3.1存储和获取方法的源码:

	// 保存属性,底层调用hashtable的put方法,该方法是线程安全的。
	public synchronized Object setProperty(String key, String value) {
        return put(key, value);
    }
	
	// 根据key获取value
	public String getProperty(String key) {
		// 调用hashtable的get方法。
        Object oval = super.get(key);
        // 判断oval 是否是String,如果是,就返回,如果不是,就是null
        String sval = (oval instanceof String) ? (String)oval : null;
        /**
         * 1.如果sval不为null,返回sval
         * 2.如果sval为null, 默认属性集存在,就去默认属性集中获取value。
         * 3.如果sval为null, 默认属性集不存在,返回null。
         */
        return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
    }
	// 根据key获取value
	public String getProperty(String key, String defaultValue) {
		String val = getProperty(key);
		// 如果没有获取到value,就返回defaultValue
        return (val == null) ? defaultValue : val;
    }
    // 获取属性集中所有key,将其存入set集合中,并返回
    public Set<String> stringPropertyNames() {
        Hashtable<String, String> h = new Hashtable<>();
        //将属性集的key和value列举,并存入hashtable中
        enumerateStringProperties(h);
        // 获取hashtable中所有key的set集合
        return h.keySet();
    }
    // 枚举方法
    private synchronized void enumerateStringProperties(Hashtable<String, String> h) {
        if (defaults != null) {
        	// 如果默认属性集存在,也进行遍历
            defaults.enumerateStringProperties(h);
        }
        //获取属性集中key的枚举,并进行遍历。
        for (Enumeration<?> e = keys() ; e.hasMoreElements() ;) {
            Object k = e.nextElement();
            // 根据key获取value
            Object v = get(k);
            if (k instanceof String && v instanceof String) {
            	// 如果key和value都是字符串,把它们都存入hashtable中。
                h.put((String) k, (String) v);
            }
        }
    }
    //和上面的方法类似,区别是它返回key的枚举,而上面的放回返回key的set集合
    public Enumeration<?> propertyNames() {
        Hashtable<String,Object> h = new Hashtable<>();
        enumerate(h);
        return h.keys();
    }
    // 枚举方法
    private synchronized void enumerate(Hashtable<String,Object> h) {
        if (defaults != null) {
        	// 如果默认属性集存在,也进行遍历
            defaults.enumerate(h);
        }
        for (Enumeration<?> e = keys() ; e.hasMoreElements() ;) {
            String key = (String)e.nextElement();
            h.put(key, get(key));
        }
    }

3.2简单演示

package com.hanyxx.io;

import java.util.Enumeration;
import java.util.Properties;
import java.util.Set;

/**
 * @author layman
 */
public class Demo01 {
    private static Properties p = new Properties();
    static{
        // 设置key和value
        p.setProperty("name1","outerMan");
        p.setProperty("name2","layman");
    }
    
    public static void main(String[] args) {
        //test01();
        test02();
    }
    // 构造带有默认属性集的Properties
    private static void test02() {
        Properties p1 = new Properties(p);
        p1.setProperty("name1","Lily");
        p1.setProperty("name3","刘大脑袋");
        p1.setProperty("name4","Rose");
        // p1中的name1和p中重复了。
        System.out.println(p1.getProperty("name1"));
        // 获取属性集中key的set集合
        Set<String> set = p1.stringPropertyNames();
        System.out.println(set);
        // 获取属性集中key的枚举集
        Enumeration<?> enums = p1.propertyNames();
        while (enums.hasMoreElements()) {
            System.out.print(enums.nextElement() + " ");
        }
    }
    // 构造空Properties
    private static void test01() {
        // 根据存在的key获取value
        System.out.println(p.getProperty("name1"));
        // 根据不存在的key获取value
        System.out.println(p.getProperty("long"));
        // 根据key获取value,如果没有,返回默认值
        System.out.println(p.getProperty("long", "18cm"));
        System.out.println(p);
    }
}
运行结果:
test01():outerMan
		 null
		 18cm
		 {name2=layman, name1=outerMan}
test02():Lily
		 [name4, name3, name2, name1]
		 name4 name3 name2 name1 

4.持久化和读取方法:

public void store(OutputStream out,String comments):将属性集合中的键值对以字节流形式写出,comments是注释信息。 
public void store(Writer writer, String comments):将属性集合中的键值对以字符流形式写出,comments是注释信息。 

public void load(InputStream inStream):从字节输入流中读取属性列表(键和元素对)。
public void load(Reader reader): 从字符输入流中读取属性列表(键和元素对)。

4.1 简单演示

package com.hanyxx.io;

import java.io.*;
import java.util.Properties;

/**
 * @author layman
 */
public class Demo01 {
    private static Properties p = new Properties();
    private static FileOutputStream fos;
    private static FileWriter fw;

    private static FileInputStream fis;
    private static FileReader fr;
    static{
        // 设置key和value
        p.setProperty("name1","outerMan");
        p.setProperty("name2","layman");
        p.setProperty("name3","钢铁侠");
        p.setProperty("name4","葫芦娃");
    }

    public static void main(String[] args) throws IOException {
        //saveFromOutputStream();
        //saveFromWriter();
        readFromInputStream();
        //readFromReader();
    }

    // 以字节流形式存储,中文会显示乱码
    private static void saveFromOutputStream() throws IOException {
        fos = new FileOutputStream("pro_字节.txt");
        String comments = "Form OutputStream";
        p.store(fos,comments);
        fos.close();
    }
    // 以字符流形式存储
    private static void saveFromWriter() throws IOException {
        fw = new FileWriter("pro_字符.txt");
        // 注释信息使用的是unicode编码,所以使用中文注释会出现乱码
        String comments = "通过字符流存储";
        p.store(fw,comments);
        fw.close();
    }

    // 以字节流形式读取,中文会显示乱码
    private static void readFromInputStream() throws IOException {
        fis = new FileInputStream("pro_字节.txt");
        p.load(fis);
        fis.close();
        System.out.println(p);
    }

    // 以字符流形式读取
    private static void readFromReader() throws IOException {
        fr = new FileReader("pro_字符.txt");
        p.load(fr);
        fr.close();
        System.out.println(p);
    }
}
posted @ 2021-03-15 15:36  layman~  阅读(47)  评论(0编辑  收藏  举报