java resourcebundle_Java - Properties和ResourceBundle类学习
一、前言
在項目的開發過程中,為了統一配置的管理,我們經常需要將一些配置信息根據環境的不同,配置在不同的properties中,然后從里面進行讀取。而Properties類作為最基礎也是最經常使用的類,通過本文我們來學習一下它的使用,然后再順便學習下其他幾種讀取properties文件的方式。
二、Properties和ResourceBundle類
Properties表示一個持久的屬性集,屬性列表通過key-value的形式存在,并且key和value都是字符串。我們先來看一下它的繼承結構:
1. Properties 繼承結構
public
class Properties extends Hashtable {
/**
* A property list that contains default values for any keys not
* found in this property list.
*
* @serial
*/
protected Properties defaults;
public Properties() {
this(null);
}
public Properties(Properties defaults) {
this.defaults = defaults;
}
}
看到它的繼承結構,就知道這個類已經存在好久了。該類繼承自Hashtable,所以該類擁有Map的一切功能,所以Map的put或者putAll方法都可以使用。
不過由于Properties中的每個key及value都是字符串,所以官方強烈反對使用它們,因為這些方法允許key或者value不是字符串,如果在set或get操作的時候,不是字符串的話,則會提示異常,所以建議使用的則是諸如setProperty這些方法。
2. Properties常用方法
這里Map相關的方法就不介紹了,主要介紹下自定義的方法:
2.1 setProperty方法
public synchronized Object setProperty(String key, String value) {
return put(key, value);
}
底層通過Hashtable的put方法來實現,該方法的目的就是強制對屬性的key和value都使用字符串的形式;
2.2 getProperties方法
public String getProperty(String key)
public String getProperty(String key, String defaultValue) {
String val = getProperty(key);
return (val == null) ? defaultValue : val;
}
獲取屬性列表中屬性的key對應的值,第二個重載方法表示如果獲取不到值返回參數中提供的默認值。
2.3 load方法
public synchronized void load(Reader reader) throws IOException
public synchronized void load(InputStream inStream) throws IOException
load方法表示從輸入流(字節流和字符流)中讀取屬性列表到Properties中,讀取的時候按照行進行讀取。而有關讀取行及相關轉義的說明,可以參考對應的API文檔,上面有詳細的說明。
2.4 loadFromXML方法
public synchronized void loadFromXML(InputStream in)
throws IOException, InvalidPropertiesFormatException
從輸入流中讀取XML文件中的所有屬性,注意XML文檔必須有相應的DTD聲明:
2.5 store方法
public void store(Writer writer, String comments)
throws IOException
public void store(OutputStream out, String comments)
throws IOException
和load的功能相反,將Properties的屬性列表寫入到輸出流,其中參數表示對屬性列表的說明。
2.6 storeToXML方法
public void storeToXML(OutputStream os, String comment)
throws IOException
public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException
將屬性寫入到xml,并可以指定的編碼格式。
2.7 propertyNames和stringPropertyNames方法
public Enumeration> propertyNames()
public Set stringPropertyNames()
兩個方法都是返回Properties屬性列表中所有key,前者返回所有枚舉,后者返回類型是字符串,注意如果沒有在主屬性列表中找到同名的鍵,則在默認屬性列表中進行查找。
2.8 list方法
public void list(PrintStream out)
public void list(PrintWriter out)
將屬性列表輸出到指定的輸出流,這個方法對調試很有用。
3. ResourceBundle簡介
ResourceBundle沒有繼承什么類,是一個單個的抽象類,該類可以說是國際化版的Properties,簡單說就是可以根據本地化或語言的不同讀取不同的配置文件,但要注意的一點是使用ResourceBundle讀取的時候,properties的命名是有一定規范的:
名稱_語言代碼_國家代碼.properties
// 如果是默認的
自定義名.properties
// 例如
myres_en_US.properties
myres_zh_CN.properties
myres.properties
當指定的Locale是CN的時候,如果myres_zh_CN.properties、myres.properties兩個文件都存在,則優先會使用myres_zh_CN.properties,當myres_zh_CN.properties不存在時候,會使用默認的myres.properties。
4. ResourceBundle常用方法
4.1 getBundle方法
ResourceBundle提供了多個重載的靜態getBundle方法,用于獲取資源文件,這里我們不多介紹,后續看實例即可:
public static final ResourceBundle getBundle(String baseName)
public static final ResourceBundle getBundle(String baseName,
Locale locale)
public static ResourceBundle getBundle(String baseName, Locale locale,
ClassLoader loader)
public static final ResourceBundle getBundle(String baseName,
Control control)
public static ResourceBundle getBundle(String baseName, Locale targetLocale,
ClassLoader loader, Control control)
4.2 getObject,getString,getStringArray方法
getString方法比較簡單,就是根據key獲取屬性列表中key對應的value,key和value都是String;
getStringArray方法,用于獲取字符串數組,返回值是字符串數組;
getObject方法,通用的獲取方法,獲取其他任何類型;
public final String getString(String key)
public final String[] getStringArray(String key)
public final Object getObject(String key)
4.3 keySet,getKeys,containsKey方法
這幾個方法都比較簡單,見名知義,其中getKeys表示返回key的枚舉形式。
public Set keySet()
public abstract Enumeration getKeys();
public boolean containsKey(String key)
4.4 getBaseBundleName,getLocale方法
getBaseBundleName方法就是獲取加載的資源文件的文件名的,getLocale獲取本地化環境信息的。
public String getBaseBundleName()
public Locale getLocale()
4.5 clearCache方法
通過getBundle方法讀取資源文件,獲取ResourceBundle時是從緩存中獲取的,如果已經緩存,工廠方法將多次返回相同的資源實例,而clearCache方法就是用于清除緩存的:
public static final void clearCache()
public static final void clearCache(ClassLoader loader)
4. 簡單示例
接下來我們來簡單看下這些方法的相關使用說明。
4.1 Properties 通過store方法寫入對應的文件中
首先我們調用setProperty方法會將key-value存于內存中,此時可以通過getProperty方法讀取,propertyNames方法進行遍歷,但是并沒有將鍵值對持久化到屬性文件中,故需要調用store方法持久化鍵值對到屬性文件中。
Properties properties = new Properties();
try {
OutputStream output = new FileOutputStream("cache.properties");
properties.setProperty("redis.server.address", "127.0.0.1");
properties.setProperty("redis.server.port", "6379");
properties.setProperty("redis.server.password", "");
properties.setProperty("redis.server.timeout", "2000");
properties.store(output, "緩存文件配置測試");
} catch (IOException io) {
io.printStackTrace();
} finally {
...
}
最終生成的cache.properties文件:
#緩存文件配置測試
#Sun Aug 19 12:27:05 CST 2018
redis.server.timeout=2000
redis.server.address=127.0.0.1
redis.server.password=
redis.server.port=6379
4.2 Properties使用load方法加載
同樣,我們可以通過load方法將屬性文件中的屬性加載到Properties對象中,然后進行訪問:
Properties properties = new Properties();
InputStream inputStream = null;
try {
inputStream = new FileInputStream("cache.properties");
properties.load(inputStream);
for (String key : properties.stringPropertyNames()) {
System.out.println(key + "=" + properties.getProperty(key));
}
} catch (IOException io) {
io.printStackTrace();
} finally {
...
}
最終結果:
redis.server.timeout=2000
redis.server.address=127.0.0.1
redis.server.password=
redis.server.port=6379
因為Properties其實是一個Map,所以Map的遍歷方式也適用于Properties,也可也借助Properties的propertyNames方法來進行遍歷:
Enumeration> e = properties.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = properties.getProperty(key);
System.out.println(key + "=" + value);
}
4.3 ResourceBundle簡單實例
我們先定義三個資源文件,放到src的根目錄下面:
myres.properties
aaa=good
bbb=thanks
myres_en_US.properties
aaa=good
bbb=thanks
myres_zh_CN.properties
aaa=好
bbb=謝謝
添加測試代碼:
public static void main(String[] args) {
Locale locale1 = new Locale("zh", "CN");
ResourceBundle resb1 = ResourceBundle.getBundle("cache", locale1);
System.out.println(resb1.getString("aaa"));
ResourceBundle resb2 = ResourceBundle.getBundle("cache", Locale.getDefault());
System.out.println(resb1.getString("aaa"));
Locale locale3 = new Locale("en", "US");
ResourceBundle resb3 = ResourceBundle.getBundle("cache", locale3);
System.out.println(resb3.getString("aaa"));
}
output:
好
好
good
這里需要注意下,通過getBundle方法來獲取的時候,參數不用加properties后綴,只需要文件名就可以了,并且默認訪問的路徑是src,如果文件保存在其他目錄,記得修改到對應的目錄。
5. 其他讀取properties文件的方法
5.1 Properties其他獲取InputStream的方法
在這里,其實讀取properties都是通過Properties來實現的,不過不同的是獲取InputStream流的方式,我們來看一下各種獲取InputStream流的方式:
從File文件獲取:
InputStream inputStream = new FileInputStream(new File ("cache.properties"));
根據ClassLoader的getResourceAsStream方法來獲取。其中該方法又分為兩種方式:
Class.getResourceAsStream(String path) : path 不以’/'開頭時默認是從此類所在的包下取資源,以’/'開頭則是從ClassPath根下獲取。其實只是通過path構造一個絕對路徑,最終還是由ClassLoader獲取資源;
Class.getClassLoader.getResourceAsStream(String path) :默認則是從ClassPath根下獲取,path不能以’/'開頭,最終是由ClassLoader獲取資源;
ServletContext.getResourceAsStream(String path):默認從WebAPP根目錄下取資源,Tomcat下path是否以’/'開頭無所謂,當然這和具體的容器實現有關;
InputStream inputStream = PropertiesTest.class.getResourceAsStream("cache.properties");
通過URL來獲取:
URL url = new URL("path");
InputStream inputStream= url.openStream();
如果是Spring環境,還可以通過ResourceLoader的getResource得到Resource,然后通過Resource的getInputStream來得到流:
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("/config/cache.properties");
inputStream = resource.getInputStream();
5.2 ResourceBundle類相關方法
前面也已經簡單介紹過,我們可以借助java.util.ResourceBundle的getBundle靜態方法來獲取資源實例:
Locale locale1 = new Locale("zh", "CN");
ResourceBundle resb1 = ResourceBundle.getBundle("cache", locale1);
另外,也可以借助實現類 PropertyResourceBundle 通過從輸入流中進行讀取:
inputStream = new FileInputStream("cache.properties");
ResourceBundle resource = new PropertyResourceBundle(inputStream);
不過如果有興趣的話可以看下PropertyResourceBundle的構造方法,它其實是借助Properties和HashMap來實現的:
public PropertyResourceBundle (InputStream stream) throws IOException {
Properties properties = new Properties();
properties.load(stream);
lookup = new HashMap(properties);
}
private Map lookup;
三、總結
到這里,就基本介紹完了Properties和ResourceBundle類及如何讀取properties文件,其實,介紹的都比較基礎,需要注意的可能就兩點吧:一是路徑的問題,二是流的關閉和異常處理問題。
總結
以上是生活随笔為你收集整理的java resourcebundle_Java - Properties和ResourceBundle类学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P2896 [USACO08FEB]一起
- 下一篇: PSP3000购机心得