java.util.Properties 的使用

方法简介

方法简介
1Properties()新建一个空的 Properties 对象
2Properties(Properties defaults)新建一个带有默认值的 Properties 对象
3load(Reader reader)从字符流中加载属性列表
4load(InputStream inStream)从字节流中加载属性列表
5setProperty(String key, String value)设置属性值
6getProperty(String key)获取属性值,若属性列表、默认属性列表都不存在,则返回 null
7getProperty(String key, String defaultValue)获取属性值,若属性列表、默认属性列表都不存在,则返回参数 defaultValue
8propertyNames()获取所有属性名的Enumeration<?>,包括主属性列表和默认属性列表中的,若碰到非 String 的键将抛出异常
9stringPropertyNames()获取所有属性名,返回值为Set<String>,且会忽略非 String 的键
10store(Writer writer, String comments)将属性列表写入字符流中,以适合 load(Reader) 方法加载的格式,默认的属性不会被写出
11store(OutputStream out, String comments)将属性列表写入字节流中,以适合 load(InputStream) 方法加载的格式,默认的属性不会被写出
12list(PrintStream out)将此属性列表打印到指定的输出流。这个方法对于调试很有用。
13list(PrintWriter out)将此属性列表打印到指定的输出流。这个方法对于调试很有用。
14loadFromXML(InputStream in)从 XML 中加载属性列表
15storeToXML(OutputStream os, String comment)将属性列表写入指定流
16storeToXML(OutputStream os, String comment, String encoding)将属性列表写入指定流

代码示例

Properties()、Properties(Properties defaults)

Properties()、Properties(Properties defaults)都是创建一个Properties对象,区别在于后者包含一个默认的属性列表,会将其赋值给defaults属性。

// Properties 继承了 Hashtable
public class Properties extends Hashtable<Object,Object> {

    /**
     * A property list that contains default values for any keys not
     * found in this property list.
     *
     * @serial
     */
    protected Properties defaults;

    /**
     * Creates an empty property list with no default values.
     */
    public Properties() {
        this(null);
    }

    /**
     * Creates an empty property list with the specified defaults.
     *
     * @param   defaults   the defaults.
     */
    public Properties(Properties defaults) {
        this.defaults = defaults;
    }
}
public static void constructor() {
	Properties prop = new Properties();
	Properties propWithDefault = new Properties(defaults());
	System.out.println("id: " + prop.getProperty("id"));
	System.out.println("id: " + propWithDefault.getProperty("id"));
}

public static Properties defaults() {
	Properties properties = new Properties();
	properties.setProperty("id", "100");
	return properties;
}

如果在主属性列表中找不到对应键的话,会到默认属性列表defaults中去寻找。

id: null
id: 100

load(Reader reader)、load(InputStream inStream)

load(Reader reader)、load(InputStream inStream)都是从流中加载属性列表,基本可以说是以行为单位。并且有以下的规则

  • 以 #、! 开头的行会被认为是注释,并被忽略
  • 空白行会被忽略
  • 可以用 = 或 : 分隔键值对
  • 键、值前后的空白字符将被忽略
  • 此方法返回后指定的流仍然保持打开的状态
  • 具体的规则、例子可以查看load(Reader reader)方法的注释

load(Reader reader)是子字符流为基础的,可以直接处理中文;load(InputStream inStream)是以字节流为基础的,且使用 ISO 8859-1 编码进行处理,会造成中文乱码。另外要注意 properties 文件的编码要是 utf-8。需要手动关闭指定的流。

# aa=aaa
! bb =bbb

Truth1 = Beauty
 Truth2:Beauty
    Truth3                    :Beauty
Truits                           apple, banana, pear, \
                                        cantaloupe, watermelon, \
                                        kiwi, mango
cheeses
name=小明
age\=18
father\:tom
public static void load() throws IOException {
	Properties prop = new Properties();
	// 使用这行代码时,小明会乱码
//        prop.load(Test1.class.getResourceAsStream("/test.properties"));
	prop.load(new InputStreamReader(Test1.class.getResourceAsStream("/test.properties"), "UTF-8"));
	prop.forEach((k, v)-> System.out.println(k + "=" + v));
}

可以看出注释被忽略了;空行被忽略了;键和值前后的空白字符都被忽略了;cheeses 的值为空字符串;中文没有乱码;7~9行这种形式的被解析成了一个键值对;\=\:被转义成了普通字符,成为了键的一部分。

Truth2=Beauty
Truth3=Beauty
cheeses=
father:tom=
age=18=
name=小明
Truits=apple, banana, pear, cantaloupe, watermelon, kiwi, mango
Truth1=Beauty

setProperty(String key, String value)

设置属性,并返回指定键的上一个值,即旧的值。

public static void setProperty() {
	Properties prop = new Properties();
	Object old1 = prop.setProperty("id", "100");
	Object old2 = prop.setProperty("id", "200");
	System.out.println("old1: " + old1);
	System.out.println("old2: " + old2);
	System.out.println("id: " + prop.get("id"));
}
old1: null
old2: 100
id: 200

getProperty(String key)、getProperty(String key, String defaultValue)

两个方法都是获取指定键对应的属性值,都会先从主属性列表中查找,若没有找到的话,再查找默认属性列表defaults,找到则直接返回,若没有找到,getProperty(String key)会返回 null,getProperty(String key, String defaultValue)会返回参数 defaultValue。若找到的属性值不是 String 类型,也按照以上的规则。

public static void getProperty() {
	Properties prop = new Properties();
	String id = prop.getProperty("id");
	String idWithDefault = prop.getProperty("id", "NO123");

	System.out.println("id: " + id);
	System.out.println("idWithDefault: " + idWithDefault);
}
id: null
idWithDefault: NO123

propertyNames()、stringPropertyNames()

两个方法都用于返回属性列表中的所有键,不同的是propertyNames()返回值是Enumeration<?>stringPropertyNames()返回值是Set<String>;当遇到非 String 的键时,propertyNames()抛出异常ClassCastExceptionstringPropertyNames()忽略非 String 的键。

public static void propertyNames() {
	Properties prop = new Properties(defaults());
	prop.setProperty("name", "tom");
	prop.setProperty("age", "18");

	// 放入一个非 String 的键
//        prop.put(new Object(), "");

	System.out.println("--stringPropertyNames--");
	Set<String> keys = prop.stringPropertyNames();
	keys.forEach(System.out::println);


	System.out.println("--propertyNames--");
	Enumeration<?> enumeration = prop.propertyNames();
	while (enumeration.hasMoreElements()) {
		Object o = enumeration.nextElement();
		System.out.println(o);
	}
}

public static Properties defaults() {
	Properties properties = new Properties();
	properties.setProperty("id", "100");
	return properties;
}

当属性列表中不存在非 String 的键时

--stringPropertyNames--
age
name
id
--propertyNames--
age
name
id

当属性列表中存在非 String 的键时

--stringPropertyNames--
age
name
id
--propertyNames--
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
	at java.util.Properties.enumerate(Properties.java:1097)
	at java.util.Properties.propertyNames(Properties.java:1008)
	at com.example.heima.properties.Test1.propertyNames(Test1.java:76)
	at com.example.heima.properties.Test1.main(Test1.java:15)

store(Writer writer, String comments)、store(OutputStream out, String comments)

将属性列表写入字符流、字节流中,以适合 load(Reader) 方法加载的格式,默认的属性不会被写出。写入之后,将 flush 输出流。此方法返回后,输出流保持打开状态。

public static void store() throws IOException {
	Properties prop = new Properties(defaults());
	prop.setProperty("name", "小明");
	prop.setProperty("age", "18");

	prop.store(new FileWriter("E:\\test1.properties"), "测试 store");
	prop.store(new FileOutputStream("E:\\test2.properties"), "测试 store");

	Properties prop1 = new Properties();
	prop1.load(new FileInputStream("E:\\test2.properties"));

	Properties prop2 = new Properties();
	prop2.load(new FileReader("E:\\test2.properties"));

	prop1.list(System.out);
	prop2.list(System.out);
}

public static Properties defaults() {
	Properties properties = new Properties();
	properties.setProperty("id", "100");
	return properties;
}

输出

-- listing properties --
age=18
name=小明
-- listing properties --
age=18
name=小明

文件内容如下,默认的属性列表没有没写入文件,比如 id;注释中的中文被编码了;使用store(OutputStream out, String comments)时会将中文的键值对进行编码。

test1.properties
#\u6D4B\u8BD5 store
#Sat Dec 26 15:56:12 CST 2020
age=18
name=小明

test2.properties
#\u6D4B\u8BD5 store
#Sat Dec 26 15:56:12 CST 2020
age=18
name=\u5C0F\u660E

list(PrintStream out)、list(PrintWriter out)

将此属性列表打印到指定的输出流。这个方法对于调试很有用。遇到非 String 的键时会抛出异常ClassCastException

public static void list() throws IOException {
	Properties prop = new Properties(defaults());
	prop.setProperty("name", "小明");
	prop.setProperty("age", "18");

	prop.list(System.out);

	prop.put(new Object(), "");
	prop.list(System.out);
}
-- listing properties --
age=18
name=小明
id=100
-- listing properties --
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
	at java.util.Properties.enumerate(Properties.java:1097)
	at java.util.Properties.list(Properties.java:1047)
	at com.example.heima.properties.Test1.list(Test1.java:110)
	at com.example.heima.properties.Test1.main(Test1.java:16)

loadFromXML(InputStream in)

从 XML 中加载属性列表,xml 必须有以下声明<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">,且 xml 必须满足上面 DTD。方法返回之后指定的流将被关闭。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>测试 loadFromXML</comment>
    <entry key="username">小明</entry>
    <entry key="email">123@qq.com</entry>
</properties>
public static void loadFromXML() throws IOException {
	Properties prop = new Properties();
	prop.loadFromXML(Test1.class.getResourceAsStream("/test.xml"));
	prop.list(System.out);
}
-- listing properties --
email=123@qq.com
username=小明

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

以 xml 文件的格式将属性列表写入指定的流中,不包含默认属性列表。storeToXML(os, comment)storeToXML(os, comment, "UTF-8")的行为是相同的。在此方法返回后,指定的流保持打开状态。

public static void storeToXML() throws IOException {
	Properties prop = new Properties(defaults());
	prop.setProperty("name", "小明");
	prop.setProperty("age", "18");

	prop.storeToXML(new FileOutputStream("E:\\test1.xml"), "测试 storeToXML");

	Properties prop1 = new Properties();
	prop1.loadFromXML(new FileInputStream("E:\\test1.xml"));

	prop1.list(System.out);
}

public static Properties defaults() {
	Properties properties = new Properties();
	properties.setProperty("id", "100");
	return properties;
}
age=18
name=小明

写出的 xml 文件内容

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>测试 storeToXML</comment>
<entry key="age">18</entry>
<entry key="name">小明</entry>
</properties>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值