首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2SE

J2SE 讀取 Properties 設定檔的六種核心方法完整實作範例

     編輯:J2SE

統一載入入口: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_PROPERTIESProperties.load(InputStream)檔案系統絕對/相對路徑外部設定檔、部署後可修改
BY_RESOURCEBUNDLEResourceBundle.getBundle()Classpath 根目錄下的 .properties 檔(無副檔名)國際化資源、唯讀設定
BY_PROPERTYRESOURCEBUNDLEnew PropertyResourceBundle(InputStream)檔案系統路徑需 ResourceBundle 功能但檔案在 classpath 外
BY_CLASSClass.getResourceAsStream()相對於該類別的路徑模組內部資源、與類別同包
BY_CLASSLOADERClassLoader.getResourceAsStream()Classpath 根目錄相對路徑共享資源、跨模組存取
BY_SYSTEM_CLASSLOADERClassLoader.getSystemResourceAsStream()系統 Classpath 根目錄應用層級全域設定

關鍵差異與選擇建議

  • FileInputStream 系列:依賴檔案系統路徑,打包成 JAR 後失效,適合外部可編輯設定。
  • Class/ClassLoader 系列:從 Classpath 載入,支援 JAR 內資源,適合隨應用程式部署的唯讀設定。
  • ResourceBundle 系列:內建國際化支援(Locale)、快取機制,適合多語系資源;但鍵值皆為 String,且預設僅讀取 .properties 檔(無副檔名)。
  • Servlet 環境:請使用 ServletContext.getResourceAsStream() 以支援 WAR 部署結構。

最佳實踐提醒

  1. 統一使用 try-with-resources (Java 7+) 自動關閉流,避免洩漏。
  2. 生產環境建議快取載入結果,避免重複 I/O。
  3. 區分「部署時固定」與「執行期可變」設定,選擇對應載入策略。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved