loadProperties 方法以下程式碼展示一個完整的工具類別 JProperties,封裝了六種讀取 Properties 檔案的標準方式,並提供 ResourceBundleAdapter 適配器將 ResourceBundle 轉為 Properties 物件。
package com.kindani;
import java.util.*;
import java.io.*;
public class JProperties {
public final static int BY_PROPERTIES = 1;
public final static int BY_RESOURCEBUNDLE = 2;
public final static int BY_PROPERTYRESOURCEBUNDLE = 3;
public final static int BY_CLASS = 4;
public final static int BY_CLASSLOADER = 5;
public final static int BY_SYSTEM_CLASSLOADER = 6;
public final static Properties loadProperties(final String name, final int type) throws IOException {
Properties props = new Properties();
InputStream in = null;
try {
switch (type) {
case BY_PROPERTIES:
in = new BufferedInputStream(new FileInputStream(name));
props.load(in);
break;
case BY_RESOURCEBUNDLE:
ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());
props = new ResourceBundleAdapter(rb);
break;
case BY_PROPERTYRESOURCEBUNDLE:
in = new BufferedInputStream(new FileInputStream(name));
rb = new PropertyResourceBundle(in);
props = new ResourceBundleAdapter(rb);
break;
case BY_CLASS:
in = JProperties.class.getResourceAsStream(name);
props.load(in);
break;
case BY_CLASSLOADER:
in = JProperties.class.getClassLoader().getResourceAsStream(name);
props.load(in);
break;
case BY_SYSTEM_CLASSLOADER:
in = ClassLoader.getSystemResourceAsStream(name);
props.load(in);
break;
}
} finally {
if (in != null) in.close();
}
return props;
}
// Servlet 環境下的替代方案(註解保留)
/*
public static Properties loadProperties(ServletContext context, String path) throws IOException {
InputStream in = context.getResourceAsStream(path);
Properties props = new Properties();
props.load(in);
in.close();
return props;
}
*/
/** ResourceBundle 適配器:將 ResourceBundle 轉為 Properties */
public static class ResourceBundleAdapter extends Properties {
private final ResourceBundle bundle;
public ResourceBundleAdapter(ResourceBundle rb) {
if (!(rb instanceof PropertyResourceBundle)) {
throw new IllegalArgumentException("僅支援 PropertyResourceBundle");
}
this.bundle = rb;
Enumeration<String> keys = rb.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
this.put(key, rb.getObject(key));
}
}
// 代理常用方法
public ResourceBundle getBundle(String baseName) { return ResourceBundle.getBundle(baseName); }
public ResourceBundle getBundle(String baseName, Locale locale) { return ResourceBundle.getBundle(baseName, locale); }
public ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) { return ResourceBundle.getBundle(baseName, locale, loader); }
public Enumeration<String> getKeys() { return bundle.getKeys(); }
public Locale getLocale() { return bundle.getLocale(); }
public Object getObject(String key) { return bundle.getObject(key); }
public String getString(String key) { return bundle.getString(key); }
public String[] getStringArray(String key) { return bundle.getStringArray(key); }
protected Object handleGetObject(String key) { return ((PropertyResourceBundle) bundle).handleGetObject(key); }
}
}
| 常數 | 核心 API | 資源來源 | 適用場景 |
|---|---|---|---|
| BY_PROPERTIES | Properties.load(InputStream) | 檔案系統絕對/相對路徑 | 外部設定檔、部署後可修改 |
| BY_RESOURCEBUNDLE | ResourceBundle.getBundle() | Classpath 根目錄下的 .properties 檔(無副檔名) | 國際化資源、唯讀設定 |
| BY_PROPERTYRESOURCEBUNDLE | new PropertyResourceBundle(InputStream) | 檔案系統路徑 | 需 ResourceBundle 功能但檔案在 classpath 外 |
| BY_CLASS | Class.getResourceAsStream() | 相對於該類別的路徑 | 模組內部資源、與類別同包 |
| BY_CLASSLOADER | ClassLoader.getResourceAsStream() | Classpath 根目錄相對路徑 | 共享資源、跨模組存取 |
| BY_SYSTEM_CLASSLOADER | ClassLoader.getSystemResourceAsStream() | 系統 Classpath 根目錄 | 應用層級全域設定 |
.properties 檔(無副檔名)。ServletContext.getResourceAsStream() 以支援 WAR 部署結構。try-with-resources (Java 7+) 自動關閉流,避免洩漏。