Java載入資源檔的兩種方法

來源:互聯網
上載者:User

處理設定檔對於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工程,目錄結構如下:

 

該工程裡有兩個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類相同的載入方法:

public InputStream getResourceAsStream(String pathToConfigFile);

 

用ClassLoader載入設定檔時,pathToConfigFile均不能以"/"開頭,在尋找時直接在classpath下進行尋找。Class類在尋找資源檔時,也是代理(delegate)給ClassLoader完成尋找功能的,請參考Java官方文檔。

 

在使用Class和ClassLoader載入資源檔時,有幾種區別細微的方法,修改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();
resourceLoader.loadProperties2();
resourceLoader.loadProperties3();
resourceLoader.loadProperties4();
resourceLoader.loadProperties5();
resourceLoader.loadProperties6();
}

public void loadProperties1() throws IOException
{
InputStream input = null;
try
{
input = Class.forName("davenkin.ResourceLoader").getResourceAsStream("/resources/config.properties");
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
printProperties(input);
}

public void loadProperties2() throws IOException
{
InputStream input = null;

input = this.getClass().getResourceAsStream("/resources/config.properties");
printProperties(input);
}

public void loadProperties3() throws IOException
{
InputStream input = this.getClass().getResourceAsStream("resources/config.properties");
printProperties(input);
}

public void loadProperties4() throws IOException
{
InputStream input = this.getClass().getClassLoader().getResourceAsStream("resources/config.properties");
printProperties(input);
}

public void loadProperties5() throws IOException
{
InputStream input = ClassLoader.getSystemResourceAsStream("resources/config.properties");
printProperties(input);
}

public void loadProperties6() throws IOException
{
InputStream input = ClassLoader.getSystemClassLoader().getResourceAsStream("resources/config.properties");

printProperties(input);
}

private void printProperties(InputStream input) throws IOException
{
Properties properties = new Properties();
properties.load(input);
System.out.println(properties.getProperty("name"));
}
}

 

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

ConfigUnderSrc
ConfigUnderSrc
ConfigUnderDavenkin
ConfigUnderSrc
ConfigUnderSrc
ConfigUnderSrc
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.