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

下面我們從寫入、讀取、遍歷等角度來解析Properties類的常見用法:
寫入
Properties類調用setProperty方法將鍵值對保存到內存中,此時可以通過getProperty方法讀取,propertyNames方法進行遍歷,但是並沒有將鍵值對持久化到屬性文件中,故需要調用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");//保存鍵值對到內存 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()方法的參數只能寫成包路徑+properties文件名,否則將拋異常 * * @return */ public static String getPath2() { ResourceBundle rb = ResourceBundle .getBundle("cn/habitdiary/prop"); path = rb.getString("path"); return path; } /** * 三、 使用java.util.PropertyResourceBundle類的構造函數 * * @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()方法的參數按格式寫到包路徑+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)方法的參數必須是包路徑+文件名+.后綴 * 否則會報空指針異常 * @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()靜態方法 * getSystemResourceAsStream()方法的參數格式也是有固定要求的 * * @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對象來操作文件內容。
第二、三中方式是通過ResourceBundle類來加載Properties文件,然后ResourceBundle對象來操做properties文件內容。
其中最重要的就是每種方式加載文件時,文件的路徑需要按照方法的定義的格式來加載,否則會拋出各種異常,比如空指針異常。
遍歷
下面給出四種遍歷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); } }