java讀取.properties配置文件的幾種方法


讀取.properties配置文件在實際的開發中使用的很多,總結了一下,有以下幾種方法(僅僅是我知道的):
一、通過jdk提供的java.util.Properties類。
此類繼承自java.util.HashTable,即實現了Map接口,所以,可使用相應的方法來操作屬性文件,但不建議使用像put、putAll這兩個方法,因為put方法不僅允許存入String類型的value,還可以存入Object類型的。因此java.util.Properties類提供了getProperty()和setProperty()方法來操作屬性文件,同時使用store或save(已過時)來保存屬性值(把屬性值寫入.properties配置文件)。在使用之前,還需要加載屬性文件,它提供了兩個方法:load和loadFromXML。
load有兩個方法的重載:load(InputStream inStream)、load(Reader reader),所以,可根據不同的方式來加載屬性文件。
可根據不同的方式來獲取InputStream,如:
1、通過當前類加載器的getResourceAsStream方法獲取

[java]  view plain  copy
 
  1. InputStream inStream = TestProperties.class.getClassLoader().getResourceAsStream("test.properties");  



2、從文件獲取

[java]  view plain  copy
 
  1. InputStream inStream = new FileInputStream(new File("filePath"));  



3、也是通過類加載器來獲取,和第一種一樣

[java]  view plain  copy
 
  1. InputStream in = ClassLoader.getSystemResourceAsStream("filePath");  



4、在servlet中,還可以通過context來獲取InputStream

[java]  view plain  copy
 
  1. InputStream in = context.getResourceAsStream("filePath");  



5、通過URL來獲取

[java]  view plain  copy
 
  1. URL url = new URL("path");  
  2. InputStream inStream = url.openStream();  



讀取方法如下:

[java]  view plain  copy
 
  1. Properties prop = new Properties();  
  2. prop.load(inStream);  
  3. String key = prop.getProperty("username");  
  4. //String key = (String) prop.get("username");  




二、通過java.util.ResourceBundle類來讀取,這種方式比使用Properties要方便一些。
1、通過ResourceBundle.getBundle()靜態方法來獲取(ResourceBundle是一個抽象類),這種方式來獲取properties屬性文件不需要加.properties后綴名,只需要文件名即可。

[java]  view plain  copy
 
  1. ResourceBundle resource = ResourceBundle.getBundle("com/mmq/test");//test為屬性文件名,放在包com.mmq下,如果是放在src下,直接用test即可  
  2. String key = resource.getString("username");  



2、從InputStream中讀取,獲取InputStream的方法和上面一樣,不再贅述。

[java]  view plain  copy
 
  1. ResourceBundle resource = new PropertyResourceBundle(inStream);  



    注意:在使用中遇到的最大的問題可能是配置文件的路徑問題,如果配置文件入在當前類所在的包下,那么需要使用包名限定,如:test.properties入在com.mmq包下,則要使用com/mmq/test.properties(通過Properties來獲取)或com/mmq/test(通過ResourceBundle來獲取);屬性文件在src根目錄下,則直接使用test.properties或test即可。

 

 

這里主要是總結使用getResourceAsStream方法和InputStream流去讀取properties文件,使用getResourceAsStream方法去讀取properties文件時需要特別注意properties文件路徑的寫法

關於getClass().getClassLoader()

 

 

InputStream   is   =   getClass().getClassLoader().getResourceAsStream("helloworld.properties");中getClass()和getClassLoader()都是什么意思呀.
getClass():取得當前對象所屬的Class對象  
getClassLoader():取得該Class對象的類裝載器
類裝載器負責從Java字符文件將字符流讀入內存,並構造Class類對象,在你說的問題哪里,通過它可以得到一個文件的輸入流
getClass :
public final Class getClass()
Returns the runtime class of an object. That Class object is the object that is locked by static synchronized methods of the represented class.
Returns:
the object of type Class that represents the runtime class of the object.


getClassLoader
public ClassLoader getClassLoader()
Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.
If a security manager is present, and the caller´s class loader is not null and the caller´s class loader is not the same as or an ancestor of the class loader for the class whose class loader is requested, then this method calls the security manager´s checkPermission method with a RuntimePermission("getClassLoader") permission to ensure it´s ok to access the class loader for the class.

If this object represents a primitive type or void, null is returned.

Returns:
the class loader that loaded the class or interface represented by this object.
Throws:
SecurityException - if a security manager exists and its checkPermission method denies access to the class loader for the class.
See Also:
ClassLoader, SecurityManager.checkPermission(java.security.Permission), RuntimePermission

Class.getClassLoader()的一個小陷阱:)
昨天我的code總在Integer.class.getClassLoader().getResource("*********");這一句拋出空指針異常,定位為getClassLoader()返回null,查了一下jdk的文檔,原來這里還有一個陷阱:
jdk中關於getClassLoader()的描述:
/**
     * Returns the class loader for the class. Some implementations may use
     * null to represent the bootstrap class loader. This method will return
     * null in such implementations if this class was loaded by the bootstrap
     * class loader.
     *
     * <p> If a security manager is present, and the caller's class loader is
     * not null and the caller's class loader is not the same as or an ancestor of
     * the class loader for the class whose class loader is requested, then
     * this method calls the security manager's <code>checkPermission</code>
     * method with a <code>RuntimePermission("getClassLoader")</code>
     * permission to ensure it's ok to access the class loader for the class.
     *
     * <p>If this object
     * represents a primitive type or void, null is returned.
.....

上面的英文可以用下面的話來理解:

裝載類的過程非常簡單:查找類所在位置,並將找到的Java類的字節碼裝入內存,生成對應的Class對象。Java的類裝載器專門用來實現這樣的過程,JVM並不止有一個類裝載器,事實上,如果你願意的話,你可以讓JVM擁有無數個類裝載器,當然這除了測試JVM外,我想不出還有其他的用途。你應該已經發現到了這樣一個問題,類裝載器自身也是一個類,它也需要被裝載到內存中來,那么這些類裝載器由誰來裝載呢,總得有個根吧?沒錯,確實存在這樣的根,它就是神龍見首不見尾的Bootstrap ClassLoader. 為什么說它神龍見首不見尾呢,因為你根本無法在Java代碼中抓住哪怕是它的一點點的尾巴,盡管你能時時刻刻體會到它的存在,因為java的運行環境所需要的所有類庫,都由它來裝載,而它本身是C++寫的程序,可以獨立運行,可以說是JVM的運行起點,偉大吧。在Bootstrap完成它的任務后,會生成一個AppClassLoader(實際上之前系統還會使用擴展類裝載器ExtClassLoader,它用於裝載Java運行環境擴展包中的類),這個類裝載器才是我們經常使用的,可以調用ClassLoader.getSystemClassLoader() 來獲得,我們假定程序中沒有使用類裝載器相關操作設定或者自定義新的類裝載器,那么我們編寫的所有java類通通會由它來裝載,值得尊敬吧。AppClassLoader查找類的區域就是耳熟能詳的Classpath,也是初學者必須跨過的門檻,有沒有靈光一閃的感覺,我們按照它的類查找范圍給它取名為類路徑類裝載器。還是先前假定的情況,當Java中出現新的類,AppClassLoader首先在類傳遞給它的父類類裝載器,也就是Extion ClassLoader,詢問它是否能夠裝載該類,如果能,那AppClassLoader就不干這活了,同樣Extion ClassLoader在裝載時,也會先問問它的父類裝載器。我們可以看出類裝載器實際上是一個樹狀的結構圖,每個類裝載器有自己的父親,類裝載器在裝載類時,總是先讓自己的父類裝載器裝載(多么尊敬長輩),如果父類裝載器無法裝載該類時,自己就會動手裝載,如果它也裝載不了,那么對不起,它會大喊一聲:Exception,class not found。有必要提一句,當由直接使用類路徑裝載器裝載類失敗拋出的是NoClassDefFoundException異常。如果使用自定義的類裝載器loadClass方法或者ClassLoader的findSystemClass方法裝載類,如果你不去刻意改變,那么拋出的是ClassNotFoundException。

這里jdk告訴我們:如果一個類是通過bootstrap 載入的,那我們通過這個類去獲得classloader的話,有些jdk的實現是會返回一個null的,比如說我用 new Object().getClass().getClassLoader()的話,會返回一個null,這樣的話上面的代碼就會出現NullPointer異常.所以保險起見我們最好還是使用我們自己寫的類來獲取classloader("this.getClass().getClassLoader()“),這樣一來就不會有問題。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM