java資源加載,getResource


  最近做項目的時候遇到的一個資源加載問題,主要涉及到從工程(從IDE中啟動項目)中加載資源文件(配置文件等)和將工程打包成jar包運行時加載資源文件的問題。

  先看一下工程目錄結構

    

config.properties就是我們需要加載的資源文件。

測試代碼如下:

package com.li;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

/**
* Created by li on 2018/7/6.
*/

class test{}

public class ResourceTest {
public static void main(String[] args) throws IOException {
System.out.println("路徑測試:");
System.out.println("XXX.class.getResource(\"/\")" + test.class.getResource("/"));
System.out.println("XXX.class.getResource(\"\")" + test.class.getResource(""));
System.out.println("XXX.class.getClassLoader().getResource(\"\")" + test.class.getClassLoader().getResource(""));
System.out.println("---------------------------------");
System.out.println("XXX.class.getResource(\"config.properties\")" + test.class.getResource("config.properties") );
System.out.println("XXX.class.getResource(\"/config.properties\")" + test.class.getResource("/config.properties") );
System.out.println("XXX.class.getClassLoader().getResource(\"config.properties\")" + test.class.getClassLoader().getResource("config.properties") );

System.out.println("輸入流測試:");
InputStream inPkg = test.class.getResourceAsStream("");
if( inPkg == null ){
System.out.println("XXX.class.getResourceAsStream(\"\")" + inPkg);
}else{
System.out.println("XXX.class.getResourceAsStream(\"\")" + " the read result is:");
read(inPkg);
}
InputStream inRoot = test.class.getResourceAsStream("/");
if( inRoot == null ){
System.out.println("XXX.class.getResourceAsStream(\"/\");" + inRoot);
}else{
System.out.println("XXX.class.getResourceAsStream(\"/\")" + " the read result is:");
read(inRoot);
}
InputStream inPkgLoader = test.class.getClassLoader().getResourceAsStream("");
if( inPkgLoader == null ){
System.out.println( "XXX.class.getClassLoader().getResourceAsStream(\"\")" + inPkgLoader );
}else {
System.out.println( "XXX.class.getClassLoader().getResourceAsStream(\"\")" + " the read result is:" );
read(inPkgLoader);
}
System.out.println("-------------------------");
InputStream inPkg1 = test.class.getResourceAsStream("config.properties");
InputStream inRoot1 = test.class.getResourceAsStream("/config.properties");
InputStream inPkgLoader1 = test.class.getClassLoader().getResourceAsStream("config.properties");
if( inPkg1 == null ){
System.out.println( "XXX.class.getResourceAsStream(\"config.properties\")" + inPkg1 );
}else {
System.out.println( "XXX.class.getResourceAsStream(\"config.properties\")" + " the read result is:" );
read(inPkg1);
}
if( inRoot1 == null ){
System.out.println( "XXX.class.getResourceAsStream(\"/config.properties\")" + inRoot1 );
}else{
System.out.println( "XXX.class.getResourceAsStream(\"/config.properties\")" + " the read result is:");
read(inRoot1);
}
if( inPkgLoader1 == null ){
System.out.println( "test.class.getClassLoader().getResourceAsStream(\"config.properties\")" + inPkgLoader1 );
}else{
System.out.println( "test.class.getClassLoader().getResourceAsStream(\"config.properties\")" + " the read result is:");
read(inPkgLoader1);
}

}

public static void read(InputStream in) throws IOException {
byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
for( int len = 0 ; (len = in.read(buffer)) != -1; ){
out.write(buffer,0,len);
}
byte[] bs = out.toByteArray();
String str = new String(bs,0,bs.length, Charset.forName("utf-8"));
System.out.println(" " + str);
}
}

主要測試為方法為:

  XXX.class.getResource();

  XXX.class.getClassLoader().getResource();

  XXX.class.getClassLoader().getResourceAsStream();

  XXX.class.getResourceAsStream();

前提條件  在項目作為一個工程在文件夾下運行時(不打成jar包運行) 

  XXX.class.getResource("A.properties");

表示讀取類XXX所屬的包下名為A.properties的配置文件。

  |--com

    |--li

      |--XXX.class

      |--A.properties

  XXX.class.getResource("/A.properties");

表示讀取類XXX根路徑下開始讀取

  |--com

    |--li

    |--XXX.class

  |--A.properties

同理XXX.class.getResourceAsStream()方法。

 

接下來在談一下

  XXX.class.getClassLoader().getResource( resourcePath );

  XXX.class.getClassLoader().getResourceAsStream( resourcePath );

當resourcePath以字符'/'開頭時,返回結果為null

 XXX.class.getClassLoader().getResource( resourcePath );

 XXX.class.getClassLoader().getResourceAsStream( resourcePath );

均為從類的根路徑開始讀取資源。

 

接下來分幾種情況來討論一下以上幾個方法具體的調用結果

1.直接在工程下運行:

  輸出結果如下:

路徑測試:
XXX.class.getResource("/")file:/Users/li/workspace/PathTest/out/production/PathTest/
XXX.class.getResource("")file:/Users/li/workspace/PathTest/out/production/PathTest/com/li/
XXX.class.getClassLoader().getResource("")file:/Users/li/workspace/PathTest/out/production/PathTest/
---------------------------------
XXX.class.getResource("config.properties")null
XXX.class.getResource("/config.properties")file:/Users/li/workspace/PathTest/out/production/PathTest/config.properties
XXX.class.getClassLoader().getResource("config.properties")file:/Users/li/workspace/PathTest/out/production/PathTest/config.properties
輸入流測試:
XXX.class.getResourceAsStream("") the read result is:
ResourceTest.class
test.class

XXX.class.getResourceAsStream("/") the read result is:
com
config.properties

XXX.class.getClassLoader().getResourceAsStream("") the read result is:
com
config.properties

-------------------------
XXX.class.getResourceAsStream("config.properties")null
XXX.class.getResourceAsStream("/config.properties") the read result is:
inProject=true
test.class.getClassLoader().getResourceAsStream("config.properties") the read result is:
inProject=true

2.項目打成jar包,並且配置文件config.properties一並打入jar包中是結果:

 

路徑測試:

XXX.class.getResource("/")null

XXX.class.getResource("")jar:file:/Users/li/cache/PathTest.jar!/com/li/

XXX.class.getClassLoader().getResource("")null

---------------------------------

XXX.class.getResource("config.properties")null

XXX.class.getResource("/config.properties")jar:file:/Users/li/cache/PathTest.jar!/config.properties

XXX.class.getClassLoader().getResource("config.properties")jar:file:/Users/li/cache/PathTest.jar!/config.properties

輸入流測試:

XXX.class.getResourceAsStream("") the read result is:



XXX.class.getResourceAsStream("/");null

XXX.class.getClassLoader().getResourceAsStream("")null

-------------------------

XXX.class.getResourceAsStream("config.properties")null

XXX.class.getResourceAsStream("/config.properties") the read result is:

inProject=true

test.class.getClassLoader().getResourceAsStream("config.properties") the read result is:

inProject=true
         

      

3.項目打成jar包,配置文件config.properties不打入jar包中,而是放在與jar包同一級別目錄下:

 

路徑測試:

XXX.class.getResource("/")null

XXX.class.getResource("")jar:file:/Users/li/cache/PathTest.jar!/com/li/

XXX.class.getClassLoader().getResource("")null

---------------------------------

XXX.class.getResource("config.properties")null

XXX.class.getResource("/config.properties")null

XXX.class.getClassLoader().getResource("config.properties")null

輸入流測試:

XXX.class.getResourceAsStream("") the read result is:



XXX.class.getResourceAsStream("/");null

XXX.class.getClassLoader().getResourceAsStream("")null

-------------------------

XXX.class.getResourceAsStream("config.properties")null

XXX.class.getResourceAsStream("/config.properties")null

test.class.getClassLoader().getResourceAsStream("config.properties")null

 

 

4.將jar包引入到項目中,並且項目的classpath下面放入config.properties配置文件,同時jar包內不放入config.properties配置文件:

路徑測試:
XXX.class.getResource("/")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
XXX.class.getResource("")jar:file:/Users/li/workspace/PathTest1/lib/PathTest.jar!/com/li/
XXX.class.getClassLoader().getResource("")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
---------------------------------
XXX.class.getResource("config.properties")null
XXX.class.getResource("/config.properties")file:/Users/li/workspace/PathTest1/out/production/PathTest1/config.properties
XXX.class.getClassLoader().getResource("config.properties")file:/Users/li/workspace/PathTest1/out/production/PathTest1/config.properties
輸入流測試:
XXX.class.getResourceAsStream("") the read result is:

XXX.class.getResourceAsStream("/") the read result is:
ccom
config.properties

XXX.class.getClassLoader().getResourceAsStream("") the read result is:
ccom
config.properties

-------------------------
XXX.class.getResourceAsStream("config.properties")null
XXX.class.getResourceAsStream("/config.properties") the read result is:
outerPkg=true
test.class.getClassLoader().getResourceAsStream("config.properties") the read result is:
outerPkg=true

5.將jar包引入到項目中,並且項目的classpath下面放入config.properties配置文件,同時jar包內放入config.properties配置文件:

路徑測試:
XXX.class.getResource("/")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
XXX.class.getResource("")jar:file:/Users/li/workspace/PathTest1/lib/PathTest.jar!/com/li/
XXX.class.getClassLoader().getResource("")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
---------------------------------
XXX.class.getResource("config.properties")null
XXX.class.getResource("/config.properties")file:/Users/li/workspace/PathTest1/out/production/PathTest1/config.properties
XXX.class.getClassLoader().getResource("config.properties")file:/Users/li/workspace/PathTest1/out/production/PathTest1/config.properties
輸入流測試:
XXX.class.getResourceAsStream("") the read result is:

XXX.class.getResourceAsStream("/") the read result is:
ccom
config.properties

XXX.class.getClassLoader().getResourceAsStream("") the read result is:
ccom
config.properties

-------------------------
XXX.class.getResourceAsStream("config.properties")null
XXX.class.getResourceAsStream("/config.properties") the read result is:
outerPkg=true
test.class.getClassLoader().getResourceAsStream("config.properties") the read result is:
outerPkg=true

6.將jar包引入到項目中,並且項目的classpath下面不放入config.properties配置文件,同時jar包內放入config.properties配置文件:

 

路徑測試:
XXX.class.getResource("/")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
XXX.class.getResource("")jar:file:/Users/li/workspace/PathTest1/lib/PathTest.jar!/com/li/
XXX.class.getClassLoader().getResource("")file:/Users/li/workspace/PathTest1/out/production/PathTest1/
---------------------------------
XXX.class.getResource("config.properties")null
XXX.class.getResource("/config.properties")jar:file:/Users/li/workspace/PathTest1/lib/PathTest.jar!/config.properties
XXX.class.getClassLoader().getResource("config.properties")jar:file:/Users/li/workspace/PathTest1/lib/PathTest.jar!/config.properties
輸入流測試:
XXX.class.getResourceAsStream("") the read result is:

XXX.class.getResourceAsStream("/") the read result is:
ccom

 

XXX.class.getClassLoader().getResourceAsStream("") the read result is:
ccom

 

-------------------------
XXX.class.getResourceAsStream("config.properties")null
XXX.class.getResourceAsStream("/config.properties") the read result is:
injarConfig=true
test.class.getClassLoader().getResourceAsStream("config.properties") the read result is:
injarConfig=true

 

ps: 當jar包內包含config.properties配置文件,而項目的classpath下面沒有包含config.properties時候,getResource()或者getResourceAsStream()方法會去jar包下面尋找配置文件,但是如果項目的classpath下面存在config.properties時候,就會加載項目classpath下的配置文件。另外注意配置文件放入項目中讀取時使用的是file:文件協議,而打包到jar后讀取使用的是jar:協議。關於jar協議,之后還會有介紹,另外,當項目依賴A.jar和B.jar,同時在A.jar和B.jar中都包含配置文件config.properties是,只會加載到其中一個jar包中的配置文件,應該是按順序遍歷jar包查找配置文件,找到就返回(這一點未進行考究,不確定)。當然可以用XXX.class.getClassLoader().getResources("config.properties");方法獲取jar包下的所有配置文件(考據了一下,spring中classpath*采用的這種方式)

 

 

 

 

        


免責聲明!

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



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