java.util.Properties 繼承自 Hashtable,不僅支持傳統 .properties 鍵值文件,還原生支持XML 格式的加載與存儲(JDK 1.5+),實現兩種格式無縫轉換。本文詳細演示 Properties 核心 API、屬性文件讀寫、XML 互轉、異常處理及最佳實踐,附完整可運行代碼。
| 方法 | 功能 | 備註 |
|---|---|---|
load(InputStream) | 從字節流加載 .properties 格式 | ISO 8859-1 編碼,非 ASCII 需轉義 |
load(Reader) | 從字符流加載 .properties 格式 | JDK 1.6+,支持指定編碼(如 UTF-8) |
loadFromXML(InputStream) | 從 XML 文檔加載屬性 | JDK 1.5+,自動識別 DTD |
store(OutputStream, comments) | 存儲為 .properties 格式 | comments 為文件頭註釋 |
store(Writer, comments) | 存儲為 .properties 格式(字符流) | JDK 1.6+,支持指定編碼 |
storeToXML(OutputStream, comment) | 存儲為 XML 格式 | JDK 1.5+,生成標準 DTD 文檔 |
storeToXML(OutputStream, comment, encoding) | 存儲為 XML 格式(指定編碼) | JDK 1.7+,推薦 UTF-8 |
getProperty(key) / setProperty(key, value) | 獲取/設置屬性值 | 線程安全(繼承 Hashtable 同步) |
list(PrintStream/PrintWriter) | 調試輸出所有屬性 | 格式:key=value |
storeToXML 生成的文檔遵循 Sun 定義的 DTD:
value1
value2
...
loadFromXML 解析時不強制要求 DOCTYPE 声明,但需符合該結構。
import java.io.*;
import java.util.Properties;
public class PropertiesXmlDemo {
public static void main(String[] args) {
Properties props = new Properties();
File propsFile = new File("config.properties");
File xmlFile = new File("config.xml");
// 1. 加載 .properties 文件
try (FileInputStream fis = new FileInputStream(propsFile)) {
props.load(fis);
System.out.println("加載 properties 成功: " + props.getProperty("db.url"));
} catch (IOException e) {
System.err.println("加載 properties 失敗: " + e.getMessage());
}
// 2. 修改屬性
props.setProperty("db.url", "jdbc:mysql://new-host:3306/mydb");
props.setProperty("new.key", "new-value");
// 3. 存儲為 .properties (備份)
try (FileOutputStream fos = new FileOutputStream("config_backup.properties")) {
props.store(fos, "Updated on " + new java.util.Date());
} catch (IOException e) { e.printStackTrace(); }
// 4. 存儲為 XML (推薦 UTF-8)
try (FileOutputStream fos = new FileOutputStream(xmlFile)) {
props.storeToXML(fos, "Converted to XML", "UTF-8");
System.out.println("轉換為 XML 成功: " + xmlFile.getAbsolutePath());
} catch (IOException e) { e.printStackTrace(); }
// 5. 從 XML 加載驗證
Properties fromXml = new Properties();
try (FileInputStream fis = new FileInputStream(xmlFile)) {
fromXml.loadFromXML(fis);
System.out.println("從 XML 加載驗證: " + fromXml.getProperty("db.url"));
} catch (IOException | InvalidPropertiesFormatException e) {
e.printStackTrace();
}
// 6. 追加模式存儲 XML (注意: storeToXML 會覆蓋整個文檔,非追加)
// 若需追加,需先 loadFromXML 再 setProperty 再 storeToXML
fromXml.setProperty("app.version", "2.0.0");
try (FileOutputStream fos = new FileOutputStream(xmlFile)) {
fromXml.storeToXML(fos, "Appended version", "UTF-8");
} catch (IOException e) { e.printStackTrace(); }
}
}
load(InputStream)/store(OutputStream) 固定使用 ISO 8859-1,中文會變亂碼(存為 Unicode 轉義 \uXXXX)。解決:JDK 1.6+ 使用 load(Reader)/store(Writer) 指定 UTF-8;XML 版本 JDK 1.7+ 使用 storeToXML(OutputStream, comment, "UTF-8")。storeToXML 每次調用覆蓋整個文件,非追加。需「讀取 → 修改 → 寫入」三步實現邏輯追加。Hashtable,所有公共方法同步,多線程環境下直接使用安全,但複合操作需外部同步(如 if (!props.containsKey(k)) props.setProperty(k,v))。loadFromXML 拋出 InvalidPropertiesFormatException(XML 結構不符)和 IOException,需分別捕獲。String 鍵值,非字符串需自行序列化(JSON、Base64 等)。@PropertySource 載入,運行期極少手動操作 Properties API。ConfigManager 統一管理「讀取-修改-寫入」事務,保證原子性(寫臨時文件再重命名)。Properties 雖屬舊 API,但其 loadFromXML/storeToXML 提供了極簡的「屬性文件 ⇄ XML」雙向轉換能力,無需引入第三方庫。掌握編碼處理、追加邏輯、線程安全邊界,即可在輕量級配置管理場景中高效應用。