Java Properties類使用詳解

概述

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

常見方法

除了從Hashtable中所定義的方法,Properties定義了以下方法:


Properties類

下面我們從寫入、讀取、遍歷等角度來解析Properties類的常見用法:

寫入

Properties類調(diào)用setProperty方法將鍵值對保存到內(nèi)存中,此時可以通過getProperty方法讀取,propertyNames方法進行遍歷,但是并沒有將鍵值對持久化到屬性文件中,故需要調(diào)用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");//保存鍵值對到內(nèi)存
            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()方法的參數(shù)只能寫成包路徑+properties文件名,否則將拋異常
     *
     * @return
     */
    public static String getPath2() {
        ResourceBundle rb = ResourceBundle
                .getBundle("cn/habitdiary/prop");
        path = rb.getString("path");
        return path;
    }

    /**
     * 三、 使用java.util.PropertyResourceBundle類的構造函數(shù)
     *
     * @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()方法的參數(shù)按格式寫到包路徑+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)方法的參數(shù)必須是包路徑+文件名+.后綴
     * 否則會報空指針異常
     * @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()靜態(tài)方法
     * getSystemResourceAsStream()方法的參數(shù)格式也是有固定要求的
     *
     * @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對象來操作文件內(nèi)容。
第二、三中方式是通過ResourceBundle類來加載Properties文件,然后ResourceBundle對象來操做properties文件內(nèi)容。
其中最重要的就是每種方式加載文件時,文件的路徑需要按照方法的定義的格式來加載,否則會拋出各種異常,比如空指針異常。

遍歷

下面給出四種遍歷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);
        }
    }

參考博客:

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,602評論 19 139
  • 一、基礎知識:1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機...
    殺小賊閱讀 2,569評論 0 4
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,734評論 18 399
  • 愛上獨自行走的人,都是人間少有的瘋子,不敢說至情至性,至少敢作敢為。一個人走陌生的路,認識陌生的朋友,背著行囊緩緩...
    路秋明閱讀 290評論 0 1
  • 關于回調(diào) 在多線程中,如果不想讓threadA阻塞那么一個很好的辦法是另外開一個線程threadB。但是此時想獲得...
    shawnxjf閱讀 335評論 0 0

友情鏈接更多精彩內(nèi)容