概述
Properties 繼承于 Hashtable。表示一個持久的屬性集,屬性列表以key-value的形式存在,key和value都是字符串。
Properties 類被許多Java類使用。例如,在獲取環(huán)境變量時它就作為System.getProperties()方法的返回值。
我們在很多需要避免硬編碼的應用場景下需要使用properties文件來加載程序需要的配置信息,比如JDBC、MyBatis框架等。Properties類則是properties文件和程序的中間橋梁,不論是從properties文件讀取信息還是寫入信息到properties文件都要經(jīng)由Properties類。
常見方法
除了從Hashtable中所定義的方法,Properties定義了以下方法:

下面我們從寫入、讀取、遍歷等角度來解析Properties類的常見用法:
寫入
Properties類調(diào)用setProperty方法將鍵值對保存到內(nèi)存中,此時可以通過getProperty方法讀取,propertyNames方法進行遍歷,但是并沒有將鍵值對持久化到屬性文件中,故需要調(diào)用store方法持久化鍵值對到屬性文件中。
package cn.habitdiary;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import junit.framework.TestCase;
public class PropertiesTester extends TestCase {
public void writeProperties() {
Properties properties = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("config.properties");
properties.setProperty("url", "jdbc:mysql://localhost:3306/");
properties.setProperty("username", "root");
properties.setProperty("password", "root");
properties.setProperty("database", "users");//保存鍵值對到內(nèi)存
properties.store(output, "Steven1997 modify" + new Date().toString());
// 保存鍵值對到文件中
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
讀取
下面給出常見的六種讀取properties文件的方式:
package cn.habitdiary;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
/**
* 讀取properties文件的方式
*
*/
public class LoadPropertiesFileUtil {
private static String basePath = "src/main/java/cn/habitdiary/prop.properties";
private static String path = "";
/**
* 一、 使用java.util.Properties類的load(InputStream in)方法加載properties文件
*
* @return
*/
public static String getPath1() {
try {
InputStream in = new BufferedInputStream(new FileInputStream(
new File(basePath)));
Properties prop = new Properties();
prop.load(in);
path = prop.getProperty("path");
} catch (FileNotFoundException e) {
System.out.println("properties文件路徑書寫有誤,請檢查!");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
/**
* 二、 使用java.util.ResourceBundle類的getBundle()方法
* 注意:這個getBundle()方法的參數(shù)只能寫成包路徑+properties文件名,否則將拋異常
*
* @return
*/
public static String getPath2() {
ResourceBundle rb = ResourceBundle
.getBundle("cn/habitdiary/prop");
path = rb.getString("path");
return path;
}
/**
* 三、 使用java.util.PropertyResourceBundle類的構造函數(shù)
*
* @return
*/
public static String getPath3() {
InputStream in;
try {
in = new BufferedInputStream(new FileInputStream(basePath));
ResourceBundle rb = new PropertyResourceBundle(in);
path = rb.getString("path");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
/**
* 四、 使用class變量的getResourceAsStream()方法
* 注意:getResourceAsStream()方法的參數(shù)按格式寫到包路徑+properties文件名+.后綴
*
* @return
*/
public static String getPath4() {
InputStream in = LoadPropertiesFileUtil.class
.getResourceAsStream("cn/habitdiary/prop.properties");
Properties p = new Properties();
try {
p.load(in);
path = p.getProperty("path");
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
/**
* 五、
* 使用class.getClassLoader()所得到的java.lang.ClassLoader的
* getResourceAsStream()方法
* getResourceAsStream(name)方法的參數(shù)必須是包路徑+文件名+.后綴
* 否則會報空指針異常
* @return
*/
public static String getPath5() {
InputStream in = LoadPropertiesFileUtil.class.getClassLoader()
.getResourceAsStream("cn/habitdiary/prop.properties");
Properties p = new Properties();
try {
p.load(in);
path = p.getProperty("path");
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
/**
* 六、 使用java.lang.ClassLoader類的getSystemResourceAsStream()靜態(tài)方法
* getSystemResourceAsStream()方法的參數(shù)格式也是有固定要求的
*
* @return
*/
public static String getPath6() {
InputStream in = ClassLoader
.getSystemResourceAsStream("cn/habitdiary/prop.properties");
Properties p = new Properties();
try {
p.load(in);
path = p.getProperty("path");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return path;
}
public static void main(String[] args) {
System.out.println(LoadPropertiesFileUtil.getPath1());
System.out.println(LoadPropertiesFileUtil.getPath2());
System.out.println(LoadPropertiesFileUtil.getPath3());
System.out.println(LoadPropertiesFileUtil.getPath4());
System.out.println(LoadPropertiesFileUtil.getPath5());
System.out.println(LoadPropertiesFileUtil.getPath6());
}
}
其中第一、四、五、六種方式都是先獲得文件的輸入流,然后通過Properties類的load(InputStream inStream)方法加載到Properties對象中,最后通過Properties對象來操作文件內(nèi)容。
第二、三中方式是通過ResourceBundle類來加載Properties文件,然后ResourceBundle對象來操做properties文件內(nèi)容。
其中最重要的就是每種方式加載文件時,文件的路徑需要按照方法的定義的格式來加載,否則會拋出各種異常,比如空指針異常。
遍歷
下面給出四種遍歷Properties中的所有鍵值對的方法:
/**
* 輸出properties的key和value
*/
public static void printProp(Properties properties) {
System.out.println("---------(方式一)------------");
for (String key : properties.stringPropertyNames()) {
System.out.println(key + "=" + properties.getProperty(key));
}
System.out.println("---------(方式二)------------");
Set<Object> keys = properties.keySet();//返回屬性key的集合
for (Object key : keys) {
System.out.println(key.toString() + "=" + properties.get(key));
}
System.out.println("---------(方式三)------------");
Set<Map.Entry<Object, Object>> entrySet = properties.entrySet();
//返回的屬性鍵值對實體
for (Map.Entry<Object, Object> entry : entrySet) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
System.out.println("---------(方式四)------------");
Enumeration<?> e = properties.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = properties.getProperty(key);
System.out.println(key + "=" + value);
}
}
參考博客: