溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Properties如何使用

發(fā)布時(shí)間:2021-12-17 17:53:22 來(lái)源:億速云 閱讀:196 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“Properties如何使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

01. 摘要

Map 的實(shí)現(xiàn)類有  HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties  等等。

Properties如何使用

02. 簡(jiǎn)介

Properties 類是 java 工具包中非常重要的一個(gè)類,比如在實(shí)際開發(fā)中,有些變量,我們可以直接硬寫入到自定義的 java 枚舉類中。

但是有些變量,在測(cè)試環(huán)境、預(yù)生產(chǎn)環(huán)境、生產(chǎn)環(huán)境,變量所需要取的值都不一樣,這個(gè)時(shí)候,我們可以通過(guò)使用 properties  文件來(lái)加載程序需要的配置信息,以達(dá)到一行代碼,多處環(huán)境都可以運(yùn)行的效果!

最常見的比如 JDBC  數(shù)據(jù)源配置文件,properties文件以.properties作為后綴,文件內(nèi)容以鍵=值格式書寫,左邊是變量名稱,右邊是變量值,用#做注釋,比如新建一個(gè)jdbc.properties文件,內(nèi)容如下:

Properties如何使用

Properties 類是 properties 文件和程序的中間橋梁,不論是從 properties 文件讀取信息,還是寫入信息到 properties  文件,都要經(jīng)由 Properties 類。

好了,嘮叨了這么多,咱們回到本文要介紹的主角Properties!

從集合 Map 架構(gòu)圖可以看出,Properties 繼承自 Hashtable,表示一個(gè)持久的 map 集合,屬性列表以 key-value  的形式存在,Properties 類定義如下:

public class Properties extends Hashtable<Object,Object> {     ...... }

Properties 除了繼承 Hashtable 中所定義的方法,Properties 也定義了以下幾個(gè)常用方法,如圖所示:

 Properties如何使用

常用方法介紹

set 方法(添加修改元素)

set 方法是將指定的 key, value 對(duì)添加到 map 里,在添加元素的時(shí)候,調(diào)用了 Hashtable 的 put 方法,與 Hashtable  不同的是, key 和 value 都是字符串。

打開 Properties 的 setProperty 方法,源碼如下:

public synchronized Object setProperty(String key, String value) {     //調(diào)用父類 Hashtable 的 put 方法     return put(key, value); }

方法測(cè)試如下:

public static void main(String[] args) {     Properties properties = new Properties();     properties.setProperty("name1","張三");     properties.setProperty("name2","張四");     properties.setProperty("name3","張五");     System.out.println(properties.toString()); }

輸出結(jié)果:

{name3=張五, name2=張四, name1=張三}

get 方法(搜索指定元素)

get 方法根據(jù)指定的 key 值返回對(duì)應(yīng)的 value,第一步是從調(diào)用 Hashtable 的 get  方法,如果有返回值,直接返回;如果沒有返回值,但是初始化時(shí)傳入了defaults變量,從 defaults變量中,也就是 Properties  中,去搜索是否有對(duì)于的變量,如果有就返回元素值。

打開 Properties 的 getProperty 方法,源碼如下:

public String getProperty(String key) {     //調(diào)用父類 Hashtable 的 get 方法     Object oval = super.get(key);     String sval = (oval instanceof String) ? (String)oval : null;      //進(jìn)行變量非空判斷     return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval; }

查看 defaults 這個(gè)變量,源碼如下:

public class Properties extends Hashtable<Object,Object> {     protected Properties defaults; }

這個(gè)變量在什么時(shí)候賦值呢,打開源碼如下:

public Properties(Properties defaults) {     this.defaults = defaults; }

可以發(fā)現(xiàn),在 Properties 構(gòu)造方法初始化階段,如果你給了一個(gè)自定義的 defaults ,當(dāng)調(diào)用 Hashtable 的 get  方法沒有搜索到元素值的時(shí)候,并且 defaults 也不等于空,那么就會(huì)進(jìn)一步在 defaults 里面進(jìn)行搜索元素值。

方法測(cè)試如下:

public static void main(String[] args) {     Properties properties = new Properties();     properties.setProperty("name1","張三");     properties.setProperty("name2","張四");     properties.setProperty("name3","張五");     //將 properties 作為參數(shù)初始化到 newProperties 中     Properties newProperties = new Properties(properties);     newProperties.setProperty("name4","李三");     //查詢key中 name1 的值     System.out.println("查詢結(jié)果:" + properties.getProperty("name1")); }

輸出結(jié)果:

通過(guò)key查詢結(jié)果:張三

load方法(加載配置文件)

load 方法,表示將 properties 文件以輸入流的形式加載文件,并且提取里面的鍵、值對(duì),將鍵值對(duì)元素添加到 map 中去。

打開 Properties 的 load 方法,源碼如下:

public synchronized void load(InputStream inStream) throws IOException {     //讀取文件流     load0(new LineReader(inStream)); }

load0 方法,源碼如下:

private void load0 (LineReader lr) throws IOException {     char[] convtBuf = new char[1024];     int limit;     int keyLen;     int valueStart;     char c;     boolean hasSep;     boolean precedingBackslash;      //一行一行的讀取     while ((limit = lr.readLine()) >= 0) {         c = 0;         keyLen = 0;         valueStart = limit;         hasSep = false;          precedingBackslash = false;         //判斷key的長(zhǎng)度         while (keyLen < limit) {             c = lr.lineBuf[keyLen];             if ((c == '=' ||  c == ':') && !precedingBackslash) {                 valueStart = keyLen + 1;                 hasSep = true;                 break;             } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {                 valueStart = keyLen + 1;                 break;             }             if (c == '\\') {                 precedingBackslash = !precedingBackslash;             } else {                 precedingBackslash = false;             }             keyLen++;         }         //獲取值的起始位置         while (valueStart < limit) {             c = lr.lineBuf[valueStart];             if (c != ' ' && c != '\t' &&  c != '\f') {                 if (!hasSep && (c == '=' ||  c == ':')) {                     hasSep = true;                 } else {                     break;                 }             }             valueStart++;         }         //獲取文件中的鍵和值參數(shù)         String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);         String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);         //調(diào)用 Hashtable 的 put 方法,將鍵值加入 map 中         put(key, value);     } }

好了,我們來(lái)在src/recources目錄下,新建一個(gè)custom.properties配置文件,內(nèi)容如下:

#定義一個(gè)變量名稱和值 userName=李三 userPwd=123456 userAge=18 userGender=男 userEmail=123@123.com

方法測(cè)試如下:

public class TestProperties  {      public static void main(String[] args) throws Exception {         //初始化 Properties         Properties prop = new Properties();         //加載配置文件         InputStream in = TestProperties .class.getClassLoader().getResourceAsStream("custom.properties");         //讀取配置文件,指定編碼格式,避免讀取中文亂碼         prop.load(new InputStreamReader(in, "UTF-8"));         //將內(nèi)容輸出到控制臺(tái)         prop.list(System.out);     } }

輸出結(jié)果:

userPwd=123456

userEmail=123@123.com

userAge=18

userName=李三

userGender=男

propertyNames方法(讀取全部信息)

propertyNames 方法,表示讀取 Properties 的全部信息,本質(zhì)是創(chuàng)建一個(gè)新的 Hashtable 對(duì)象,然后將原 Hashtable  中的數(shù)據(jù)復(fù)制到新的 Hashtable 中,并將 map 中的 key 全部返回。

打開 Properties 的 propertyNames 方法,源碼如下:

public Enumeration<?> propertyNames() {     Hashtable<String,Object> h = new Hashtable<>();     //將原 map 添加到新的 Hashtable 中     enumerate(h);     //返回 Hashtable 中全部的 key 元素     return h.keys(); }

enumerate 方法,源碼如下:

private synchronized void enumerate(Hashtable<String,Object> h) {     //判斷 Properties 中是否有初始化的配置文件     if (defaults != null) {         defaults.enumerate(h);     }     //將原 Hashtable 中的數(shù)據(jù)添加到新的 Hashtable 中     for (Enumeration<?> e = keys() ; e.hasMoreElements() ;) {         String key = (String)e.nextElement();         h.put(key, get(key));     } }

方法測(cè)試如下:

public static void main(String[] args) throws Exception {     //初始化 Properties     Properties prop = new Properties();     //加載配置文件     InputStream in = TestProperties.class.getClassLoader().getResourceAsStream("custom.properties");     //讀取配置文件,指定讀取編碼 UTF-8,防止內(nèi)容亂碼     prop.load(new InputStreamReader(in, "UTF-8"));     //獲取 Properties 中全部的 key 元素     Enumeration enProp = prop.propertyNames();     while (enProp.hasMoreElements()){         String key = (String) enProp.nextElement();         String value = prop.getProperty(key);         System.out.println(key + "=" + value);     } }

輸出內(nèi)容如下:

userPwd=123456

userEmail=123@123.com

userAge=18

userName=李三

userGender=男

總結(jié)

Properties 繼承自 Hashtable,大部分方法都復(fù)用于 Hashtable,比如,get、put、remove、clear 方法,**與  Hashtable 不同的是, Properties中的 key 和 value 都是字符串,**如果需要獲取 properties  中全部?jī)?nèi)容,可以先通過(guò)迭代器或者 propertyNames 方法獲取 map 中所有的 key 元素,然后遍歷獲取 key 和 value。

需要注意的是,Properties 中的 setProperty 、load 方法,都加了synchronized同步鎖,用來(lái)控制線程同步。

03. properties 文件的加載方式

在實(shí)際開發(fā)中,經(jīng)常會(huì)遇到讀取配置文件路徑找不到,或者讀取文件內(nèi)容亂碼的問題,下面簡(jiǎn)單介紹一下,properties 文件的幾種常用的加載方式。

properties 加載文件的方式,大致可以分兩類,第一類是使用 java.util.Properties 的 load 方法來(lái)加載文件流;第二類是使用  java.util.ResourceBundle 類來(lái)獲取文件內(nèi)容。

在src/recources目錄下,新建一個(gè)custom.properties配置文件,文件編碼格式為UTF-8,內(nèi)容還是以剛剛那個(gè)測(cè)試為例,各個(gè)加載方式如下!

通過(guò)文件路徑來(lái)加載文件

這類方法加載文件,主要是調(diào)用 Properties 的 load 方法,獲取文件路徑,讀取文件以流的形式加載文件。

方法如下:

Properties prop = new Properties(); //獲取文件絕對(duì)路徑 String filePath = "/coding/java/src/resources/custom.properties"; //加載配置文件 InputStream in = new FileInputStream(new File(filePath)); //讀取配置文件 prop.load(new InputStreamReader(in, "UTF-8")); System.out.println("userName:"+prop.getProperty("userName"));

輸出結(jié)果:

userName:李三 

通過(guò)當(dāng)前類加載器的getResourceAsStream方法獲取

這類方法加載文件,也是調(diào)用 Properties 的 load  方法,不同的是,通過(guò)類加載器來(lái)獲取文件路徑,如果當(dāng)前文件是在src/resources目錄下,那么直接傳入文件名就可以了。

方法如下:

Properties prop = new Properties(); //加載配置文件 InputStream in = TestProperties.class.getClassLoader().getResourceAsStream("custom.properties"); //讀取配置文件 prop.load(new InputStreamReader(in, "UTF-8")); System.out.println("userName:"+prop.getProperty("userName"));

輸出結(jié)果:

userName:李三

使用ClassLoader類的getSystemResourceAsStream方法獲取

和上面類似,也是通過(guò)類加載器來(lái)獲取文件流,方法如下:

Properties prop = new Properties();//加載配置文件InputStream in =  ClassLoader.getSystemResourceAsStream("custom.properties");//讀取配置文件prop.load(new  InputStreamReader(in,  "UTF-8"));System.out.println("userName:"+prop.getProperty("userName"));

輸出結(jié)果:

userName:李三

使用 ResourceBundle 類加載文件

ResourceBundle 類加載文件,與 Properties 有所不同,ResourceBundle 獲取 properties  文件不需要加.properties后綴名,只需要文件名即可。

ResourceBundle 是按照iso8859編碼格式來(lái)讀取原屬性文件,如果是讀取中文內(nèi)容,需要進(jìn)行轉(zhuǎn)碼處理。

方法如下:

//加載custom配置文件,不需要加`.properties`后綴名 ResourceBundle resource = ResourceBundle.getBundle("custom"); //轉(zhuǎn)碼處理,解決讀取中文內(nèi)容亂碼問題 String value = new String(resource.getString("userName").getBytes("ISO-8859-1"),"UTF-8"); System.out.println("userName:"+value);

輸出結(jié)果:

userName:李三

“Properties如何使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI