天天看點

Java加載資源檔案的兩種方法

處理配置檔案對于java程式員來說再常見不過了,不管是servlet,spring,抑或是structs,都需要與配置檔案打交道。java将配置檔案當作一種資源(resource)來處理,并且提供了兩個類來讀取這些資源,一個是class類,另一個是classloader類。

當我們自己的程式需要處理配置檔案時(比如xml檔案或properties檔案),通常會遇到兩個問題:

(1)我的配置檔案應該放在哪裡?

(2)怎麼我的配置檔案找不到了?

在了解了java加載資源檔案的機制後,以上這兩個問題便迎刃而解了。

對于第一個問題,答案是:請将你的資源檔案放在classpath裡,如果資源檔案在jar中,請将該jar檔案也加到classpath裡面。

對于第二個問題,就得看你是使用的是哪個類(class還是classloader)來加載資源檔案了,是以接下來分别讨論一下class類和classloader類對于資源檔案的加載機制。

(一)用class類加載資源檔案

通過調用class類的getresourceasstream方法來加載資源檔案:

public inputstream getresourceasstream(string pathtoconfigfile);

該方法接收一個string類型的參數(pathtoconfigfile)來表示資源檔案的位址,如果加載成功,則傳回該資源檔案的輸入流(inputstream),如果失敗,則傳回null。重要的是,在傳入pathtoconfigfile參數時,有兩種方式,第一種方式為絕對定位方式,即pathtoconfigfile以"/"開頭,此時java以classpath為根目錄,直接加上pathtoconfigfile來搜尋資源檔案。第二種方式為相對定位方式,即pathtoconfigfile不以"/"開頭,此時資源檔案的全路徑應該為:調用getresourceasstream方法的類的package路徑加上pathtoconfigfile。(在将package轉為目錄時将"."變成"/")

舉個例子,在intellij idea中建立一個java工程,目錄結構如下:

Java加載資源檔案的兩種方法

該工程裡有兩個resources檔案夾,一個位于davenkin檔案夾下,一個直接位于src檔案夾下。第一個resources檔案夾下有一個config.properties檔案,其内容為:

name = configunderdavenkin

第二個resources檔案夾下也有一個config.properties檔案,其内容為:

name = configundersrc

在davenkin包下定義resourceloader.java來加載資源檔案:

package davenkin;

import java.io.ioexception;

import java.io.inputstream;

import java.util.properties;

public class resourceloader

{

public static void main(string[] args) throws ioexception

resourceloader resourceloader = new resourceloader();

resourceloader.loadproperties1();

}

public void loadproperties1() throws ioexception

inputstream input = null;

try

input = class.forname("davenkin.resourceloader").getresourceasstream("/resources/config.properties");

//also can be this way: //input = this.getclass().getresourceasstream("/resources/config.properties"); } catch (classnotfoundexception e)

e.printstacktrace();

printproperties(input);

private void printproperties(inputstream input) throws ioexception

properties properties = new properties();

properties.load(input);

system.out.println(properties.getproperty("name"));

輸出結果為第二個resources檔案夾下config.properties的内容:

configundersrc

原因在于(請注意reourceloader.java檔案中的紅色部分):我們給出的資源檔案路徑(/resources/config.properties)以"/"開頭,即使用的是絕對定位方式,是以找到的是直接在classpath下的resources檔案夾。如果去掉資源檔案檔案路徑前的"/",則采用的是相對定位方式,此時應該輸出davenkin/resources/config.properties檔案的内容。

(二)用classloader類加載資源檔案

classloader類也提供和class類相同的加載方法:

用classloader加載配置檔案時,pathtoconfigfile均不能以"/"開頭,在查找時直接在classpath下進行查找。class類在查找資源檔案時,也是代理(delegate)給classloader完成查找功能的,請參考java官方文檔。

在使用class和classloader加載資源檔案時,有幾種差別細微的方法,修改resourceloader.java檔案如下:

resourceloader.loadproperties2();

resourceloader.loadproperties3();

resourceloader.loadproperties4();

resourceloader.loadproperties5();

resourceloader.loadproperties6();

} catch (classnotfoundexception e)

public void loadproperties2() throws ioexception

input = this.getclass().getresourceasstream("/resources/config.properties");

public void loadproperties3() throws ioexception

inputstream input = this.getclass().getresourceasstream("resources/config.properties");

public void loadproperties4() throws ioexception

inputstream input = this.getclass().getclassloader().getresourceasstream("resources/config.properties");

public void loadproperties5() throws ioexception

inputstream input = classloader.getsystemresourceasstream("resources/config.properties");

public void loadproperties6() throws ioexception

inputstream input = classloader.getsystemclassloader().getresourceasstream("resources/config.properties");

以上程式輸出結果為(請仔細揣摩,稍不小心(比如多加了一個"/"或少加了一個"/"),就會報nullpointerexception異常,表明你的資源檔案沒有找到):

configunderdavenkin