(轉)java getResourceAsStream的使用方法


背景:對於java項目中配置文件加載時候的絕對路徑和相對路徑做一個清晰的認識!

1 分析路徑

Java項目中會經常用到getResourceAsStream這個函數獲取一些配置文件,但是怎樣正確使用這個函數呢?

1.1 熟悉根目錄結構

getResourceAsStream(String path)這個函數的參數是一個路徑,但是這個路徑應該怎么填?使用該函數的難點也就在此。

其實只要記住一個關鍵點,getResourceAsStream這個函數尋找文件的起點是JAVA項目編譯之后的根目錄,比如一般maven項目編譯之后根目錄都是target/classes這個文件,舉個例子,比如下面這個目錄樹就是一個maven項目編譯之后的文件分布情況:
.
├── auth.server.properties
├── com
│   ├── winwill
│   │   └── test
│   │       ├── TestConstants.class
│   │       ├── TestConstants$HOST.class
│   │       ├── TestGetResourceAsStream.class
│   │       └── TestGuava.class
│   └── xiaomi
│       └── xmpush
│           └── iOS
│               ├── IOSPushTest.class
│               ├── UploadCertificate$1.class
│               └── UploadCertificate.class
├── config
│   └── config2.properties
├── config.properties
├── kafka-consumer.properties
├── kafka-producer.properties
├── META-INF
│   ├── MANIFEST.MF
│   └── maven
│       └── com.winwill.test
│           └── test
│               ├── pom.properties
│               └── pom.xml
├── Redis.properties
└── zookeeper.properties

我們在TestGetResourceAsStream.class這個類中應該怎么獲取config.properties和config2.properties這兩個文件呢?

ps:要想查看項目的根目錄結構,可以直接查看項目所在目錄下的classes文件目錄。例如下面的項目不屬於maven項目

項目結構:

 

編譯后的根目錄結構:

1.2 使用getClass().getResourceAsStream(String path)

ps: path 不以’/'開頭時默認是從此類所在的包下取資源,以’/'開頭則是從ClassPath根下獲取。

從上面的目錄樹可以看到,config這個文件的路徑是/config.properties(/表示根目錄),config2.properties這個文件的路徑是/config/config2.properties,

所以我們可以使用下面的代碼獲取這兩個文件——從根下獲取資源

package com.winwill.test; import org.junit.Test; import java.io.IOException; import java.io.InputStream; /** * Created by qifuguang on 14-9-28. */  
public class TestGetResourceAsStream { @Test public void getResourceClassAndFileInSamePackage() throws IOException { // 獲取config2.properties 
        InputStream config2 = this.getClass().getResourceAsStream("/config/config2.properties"); // 獲取config.properties 
        InputStream config = this.getClass().getResourceAsStream("/config.properties"); } } 

上面的代碼使用的是從根目錄開始的絕對路徑。

那么可不可以使用相對路徑呢?當然可以,請看下面的代碼——從類所在的包下獲取資源

package com.winwill.test; import org.junit.Test; import java.io.IOException; import java.io.InputStream; /** * Created by qifuguang on 14-9-28. */  
public class TestGetResourceAsStream { @Test public void getResourceClassAndFileInSamePackage() throws IOException { // 獲取config2.properties 
        InputStream config2 = this.getClass().getResourceAsStream("../../../config/config2.properties"); // 獲取config.properties 
        InputStream config = this.getClass().getResourceAsStream("../../../config.properties"); System.out.println(config + " " + config2); } } 

代碼中的兩個路徑就是這兩個文件相對TestGetResourceAsStream.class這個文件的的相對路徑

1.3 使用getClass().getClassLoader().getResourceAsStream(String path)

ps:默認是從ClassPath根下獲取,path不能以’/'開頭,最終是由ClassLoader獲取資源。

getClass().getClassLoader().getResourceAsStream()默認使用的路徑就是class文件的根目錄,所以使用getClass().getClassLoader().getResourceAsStream()來獲取文件的時候不能在路徑前面加上/,於是我們可以這樣獲取這兩個文件:

package com.winwill.test; import org.junit.Test; import java.io.IOException; import java.io.InputStream; /** * Created by qifuguang on 14-9-28. */  
public class TestGetResourceAsStream { @Test public void getResourceClassAndFileInSamePackage() throws IOException { // 獲取config2.properties 
        InputStream config2 = this.getClass().getClassLoader().getResourceAsStream("config/config2.properties"); // 獲取config.properties 
        InputStream config = this.getClass().getClassLoader().getResourceAsStream("config.properties"); } } 

 1.4  WebAPP根目錄下取資源

 ServletContext. getResourceAsStream(String path):默認從WebAPP根目錄下取資源,Tomcat下path是否以’/'開頭無所謂,當然這和具體的容器實現有關。

 Jsp下的application內置對象就是上面的ServletContext的一種實現。

 


免責聲明!

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



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