原文同步發表至我的博客【夜月歸途】html
原文連接:http://www.guitu18.com/se/java/2019-02-22/29.htmljava
在Java中常常會須要讀取各類各樣的配置文件,在獲取資源時,通常會用到 Class.getResource()
或 ClassLoader.getResource()
;編程
那麼這兩種方式在獲取資源文件時有什麼相同或者不一樣的地方呢?app
先貼上代碼目錄結構:測試
┌─src │ └─main │ └─java │ └─com.guitu18.blog │ ├─classpath │ │ └─GetResourceTest.java │ └─SpringbootApplication.java └─resource ├─mapper │ └─BlogDao.xml └─confog.properties
測試代碼,先看 this.getClass().getResource()
:
代碼的輸出結果我直接貼在代碼的上一行了,下同。ui
@Test public void classGetResource() { // file:/E:/repo/guitu-blog/target/test-classes/com/guitu18/blog/classpath/ System.out.println(this.getClass().getResource("")); // file:/E:/repo/guitu-blog/target/test-classes/ System.out.println(this.getClass().getResource("/")); }
能夠看出,getResource("")
獲取的是當前類所在包的路徑,而 getResource("/")
獲取的是 classpath
根路徑;this
繼續測試,咱們獲取目錄下的文件:url
@Test public void classGetProperties() { // file:/E:/repo/guitu-blog/target/classes/config.properties System.out.println(this.getClass().getResource("/config.properties")); // null System.out.println(this.getClass().getResource("BlogDao.xml")); // file:/E:/repo/guitu-blog/target/classes/mapper/BlogDao.xml System.out.println(this.getClass().getResource("/mapper/BlogDao.xml")); /** * .java文件在編譯後編程.class,因此這裏參數傳的文件名是.class結尾 */ // file:/E:/repo/guitu-blog/target/classes/com/guitu18/blog/classpath/GetResourceTest.class System.out.println(this.getClass().getResource("GetResourceTest.class")); // file:/E:/repo/guitu-blog/target/classes/com/guitu18/blog/SpringbootApplication.class System.out.println(this.getClass().getResource("../SpringbootApplication.class")); // file:/E:/repo/guitu-blog/target/classes/com/guitu18/blog/classpath/GetResourceTest.class System.out.println(this.getClass().getResource("../classpath/GetResourceTest.class")); }
輸出結果顯示:spa
"/"
開頭時,是從 classpath
路徑開始匹配資源;"/"
開頭時,是從當前類所在包的路徑開始匹配資源;"/"
或 "../"
在文件夾上下層路徑切換;另外,在獲取文件時,咱們還能夠經過 getResourceAsStream
直接獲取文件輸入流,如:code
InputStream inputStream = this.getClass().getResourceAsStream("/config.properties");
且 getResourceAsStream()
和 getResource()
在獲取文件流和文件路徑時,路徑選擇機制是同樣的。
接着看 this.getClass().getClassLoader().getResource
,上代碼:
@Test public void classLoaderGetResource() { // file:/E:/repo/guitu-blog/target/test-classes/ System.out.println(this.getClass().getClassLoader().getResource("")); // null System.out.println(this.getClass().getClassLoader().getResource("/")); }
在使用 ClassLoader().getResource
獲取路徑時,不能以 "/"
開頭,且路徑老是從 classpath
根路徑開始;
@Test public void classLoaderGetProperties() { /** * 一樣能夠經過"/"或"../"在文件夾上下層路徑切換 */ // file:/E:/repo/guitu-blog/target/classes/config.properties System.out.println(this.getClass().getClassLoader().getResource("config.properties")); // null System.out.println(this.getClass().getClassLoader().getResource("BlogDao.xml")); // file:/E:/repo/guitu-blog/target/classes/mapper/BlogDao.xml System.out.println(this.getClass().getClassLoader().getResource("mapper/BlogDao.xml")); /** * 同Class.getResourceAsStream()同樣,咱們還能夠經過ClassLoader.getResourceAsStream()直接獲取文件輸入流 * ClassLoader.getResourceAsStream()和ClassLoader.getResource()在獲取文件流和文件路徑時,路徑選擇機制也是同樣的 */ InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties"); }
這裏跟上面差異不大,因此直接把結果寫在代碼註釋中了, ClassLoader().getResource
只能從 classpath
開始獲取資源,一樣也能使用getResourceAsStream()
獲取文件輸入流,且路徑機制同樣;
Class.getResource()
能夠從當前 Class
所在包的路徑開始匹配獲取資源,也能夠從 classpath
根路徑開始匹配獲取資源;ClassLoader().getResource()
只能從 classpath
根路徑開始匹配獲取資源;Class.getResource()
從當前包所在路徑獲取資源時不能以 "/"
開頭,而從 classpath
根路徑獲取資源時必須以 "/"
開頭;ClassLoader().getResource()
不能以 "/"
開頭,且路徑老是從 classpath
根路徑開始;getResourceAsStream()
方法獲取對應路徑文件的輸入流,文件路徑匹配機制和其 getResource()
方法同樣;