java.util.Properties 繼承自 Hashtable,專門用於儲存鍵值對設定資料。檔案格式為純文字,支援註解、續行、逸出字元,是 Java 應用程式最常見的設定檔格式。
# 這是註解(井號開頭)
! 這也是註解(驚嘆號開頭)
# 基本鍵值對
app.name = MyApplication
db.url = jdbc:mysql://localhost:3306/mydb
# 值可包含逸出序列
path = C:\\Users\\Admin\\Documents
message = 歡迎使用\t系統\n換行測試
# 長值可用反斜線續行
long.text = 這是一段很長的文字 \
續行寫入 \
不會有空格
# 階層式鍵名(慣例用點分隔)
database.host = localhost
database.port = 3306
database.username = admin
| 方法 | 說明 |
|---|---|
load(InputStream) | 從輸入串流載入(ISO-8859-1 編碼) |
load(Reader) | 從 Reader 載入(可指定編碼,Java 1.6+) |
store(OutputStream, String) | 寫入輸出串流,第二參數為註解 |
store(Writer, String) | 寫入 Writer(可指定編碼,Java 1.6+) |
getProperty(key) | 取得值,找不到回傳 null |
getProperty(key, default) | 取得值,找不到回傳預設值 |
setProperty(key, value) | 設定值(同 put,但限制 String) |
stringPropertyNames() | 取得所有鍵名(String 集合) |
Properties props = new Properties();
try (InputStream in = new FileInputStream("config.properties")) {
props.load(in);
} catch (IOException e) {
// 處理例外:檔案不存在、權限不足等
e.printStackTrace();
}
String dbUrl = props.getProperty("db.url", "jdbc:mysql://localhost:3306/default");
int port = Integer.parseInt(props.getProperty("db.port", "3306"));
Properties props = new Properties();
props.setProperty("app.version", "1.2.3");
props.setProperty("build.time", new java.util.Date().toString());
try (OutputStream out = new FileOutputStream("config.properties")) {
props.store(out, "Application Configuration - Updated " + new java.util.Date());
} catch (IOException e) {
e.printStackTrace();
}
預設 load(InputStream) 使用 ISO-8859-1,中文會變亂碼。建議用 Reader/Writer 指定 UTF-8:
// 讀取 UTF-8
try (Reader reader = new InputStreamReader(new FileInputStream("config.properties"), StandardCharsets.UTF_8)) {
props.load(reader);
}
// 寫入 UTF-8
try (Writer writer = new OutputStreamWriter(new FileOutputStream("config.properties"), StandardCharsets.UTF_8)) {
props.store(writer, "UTF-8 編碼設定檔");
}
// 同套件目錄下
try (InputStream in = getClass().getResourceAsStream("config.properties")) {
if (in != null) props.load(in);
}
// 絕對路徑(從 classpath 根目錄)
try (InputStream in = getClass().getResourceAsStream("/config/app.properties")) {
if (in != null) props.load(in);
}
Properties defaults = new Properties();
try (InputStream in = getClass().getResourceAsStream("/default.properties")) {
defaults.load(in);
}
Properties userProps = new Properties(defaults); // 以 defaults 為預設值
try (InputStream in = new FileInputStream("user.properties")) {
userProps.load(in);
}
// userProps 現在包含:default.properties 的所有值 + user.properties 覆蓋的值
// 存為 XML
try (OutputStream out = new FileOutputStream("config.xml")) {
props.storeToXML(out, "XML 格式設定");
}
// 從 XML 讀取
try (InputStream in = new FileInputStream("config.xml")) {
props.loadFromXML(in);
}
XML 格式優點:原生支援 UTF-8、結構化、可驗證。
public final class PropsUtil {
private PropsUtil() {}
public static Properties loadFromClasspath(String path) {
Properties p = new Properties();
try (InputStream in = PropsUtil.class.getResourceAsStream(path)) {
if (in != null) p.load(in);
} catch (IOException e) {
throw new RuntimeException("載入設定檔失敗: " + path, e);
}
return p;
}
public static Properties loadFromFile(String filePath, Charset charset) {
Properties p = new Properties();
try (Reader r = new InputStreamReader(new FileInputStream(filePath), charset)) {
p.load(r);
} catch (IOException e) {
throw new RuntimeException("載入設定檔失敗: " + filePath, e);
}
return p;
}
public static void saveToFile(Properties props, String filePath, Charset charset, String comment) {
try (Writer w = new OutputStreamWriter(new FileOutputStream(filePath), charset)) {
props.store(w, comment);
} catch (IOException e) {
throw new RuntimeException("儲存設定檔失敗: " + filePath, e);
}
}
}
load(InputStream) 強制 ISO-8859-1,中文必須用 native2ascii 轉 Unicode 逸出(如 \u4e2d\u6587),或改用 load(Reader)setProperty 只改記憶體,需呼叫 store 才寫入檔案Properties 是 Java 輕量級設定管理的標準選擇。關鍵點:讀寫時明確指定 UTF-8 編碼、善用 getProperty(key, default) 避免空指標、理解其非執行緒安全特性。現代 Spring Boot 專案通常改用 YAML (@ConfigurationProperties),但 Properties 仍是基礎且通用的技能。