classloader.getresources() 介紹

轉載自: https://www.cnblogs.com/bhlsheji/p/4095699.htmlhtml

◆普通狀況下,咱們都使用相對路徑來獲取資源,這種靈活性比較大.java

比方當前類爲com/bbebfe/Test.classapache

而圖像資源比方sample.gif應該放置在com/bbebfe/sample.giftomcat

而假設這些圖像資源放置在icons文件夾下,則應該是com/bbebfe/icons/sample.gifdom

經過當前類文件的路徑獲取資源主要有例如如下幾種方式:eclipse

· 若是當前類爲com.bbebfe.Testui

· 包所在的目錄爲binthis

String imageName = "icons/sample.gif"url

1, 經過Class.getResource()定位類路徑下的資源(bin/com/bbebfe/icons/sample.gif)spa

Class clazz = this.getClass();

URL url = clazz.getResource(imageName);

2,經過ClassLoader.getResource()定位包的根文件夾下的資源(bin/icons/sample.gif)

Class clazz = this.getClass();

URLClassLoader loader = (URLClassLoader)clazz.getClassLoader();

URL url = loader.getResource(imageName);

3, 經過ClassLoader.findResource()提供本身定製的方式定位資源

URL url = loader.findResource(imageName);

 

◆那麼這三種方法有那些差異, 咱們應該在什麼時候使用哪一種方法呢?

· Class.getResource() 方法

該方法實際經過該Class的Class Loader的getResource()方法來得到資源, 在調用ClassLoader的getResource()方法以前, Class.getResource()方法會對資源名稱作必定的處理,構建一個該資源的絕對名稱(absolute name, 大意是:

       +假設資源名稱以'/'('"u002f') 開始, 則資源的絕對名稱是'/'之後的部分.

              假設imageName是"/icons/sample.gif", 則在這裏會變成"icons/sample.gif"

       +不然對於其它狀況, 絕對名稱將是例如如下形式(給資源名稱的前面加上modified_package_name/):
              modified_package_name/resource_name (修正的包名稱/資源名稱)

當中修正的包名稱含義是將當前對象所在的包名稱中的'.'('"u002e')替換爲'/'

假設ClassLoader.getResource()方法返回一個值爲null的URL, 則Class.getResource()方法終於會將資源請求交給ClassLoader.getSystemResource(java.lang.String).

· ClassLoader.getResource() 方法

該對資源進行查找, 資源的名稱是以'/'分隔的路徑, 這種方法首先查找本身的父親ClassLoader,由本身的父ClassLoader來查找資源(實際上, 假設父親的父親不是空, 則父親仍會向上提交查找請求). 假設本身的父ClassLoader是null, 則查找Java虛擬機中內建的class loader, 並將資源請求提交給它們, 假設這些操做都失敗了, 則ClassLoader會調用本身的findResource()方法來查找資源.

· ClassLoader.findResource() 方法

該方法在內部查找指定的資源, 假設你實現了本身的Class Loader,則應該重載這種方法以本身特定的方式來查找類文件和資源.

 

◆經過以上的總結, 咱們可以看到三點.

1, 無論是getResource(), 仍是findResource(), 這些方法都僅僅是資源的定位方法, 終於都僅僅是返回一個URL, 僅僅是對資源的定位而已, 咱們隨後應經過本身的方法來讀取這些資源. 而在Class和ClassLoader中還定義的有getResourceAsStream方法, 該方法是getResource的加強版, 這裏就不介紹了.

2,假設需要以類爲相對路徑查找資源, 則應該調用Class.getResource()方法, 不要直接調用ClassLoader.getResource()方法. 另外, 除非是你自定義了ClassLoader並重載了findResource方法,不然也不要直接調用ClassLoader.findResource方法, 因爲在Class.getResource()方法中會對資源名稱做必定的處理, 這在上面介紹了, 如下舉個實例:

       若是個人當前類在EclipseprojectDatabase下, 類所在的包是com.bbebfe.test, 而icons文件夾放在bin/com/bbebfe/test/文件夾下, 我需要獲得icons/sample.gif文件的URL, 則調用this.getClass().getResource()獲得的URL是:

      file:/E:/MyLife/MyProjects/Eclipse3.2/Database/bin/com/bbebfe/test/icons/disremove.gif

 

3, 有時候咱們但願某個jar庫的圖像資源在同一個icons下統一管理, 而不是爲每個包如下的Class建一個icons, 也就是說需要以庫爲相對路徑來查找資源, 此時則應該調用ClassLoader.getResource()方法, 舉個樣例:

·某個project有例如如下的包結構:

       com.bbebfe.ui

       com.bbebfe.test

       com.bbebfe.database

·假設以類爲相對路徑, 則在每個包下都必須創建一個icons文件夾, 並放置對應的資源文件. 例如如下:

       com.bbebfe.ui/icons/...

       com.bbebfe.test/icons/...

       com.bbebfe.database/icons/...

·而咱們可能但願在根文件夾下放置一個icons文件夾, 把所有資源放置在這裏管理, 這樣還可以防止資源的反覆. 就是例如如下形式

       com.bbebfe.ui

       com.bbebfe.test

       com.bbebfe.database

       icons/sample.gif ...

       則此時咱們應該調用ClassLoader.getResource方法, 由於它沒有對資源名稱做處理, 也就是說沒有將修正的包名加入到資源名稱前, 因此它會在類所在的包的根下去查找資源.(執行java程序的語法是java com.bbebfe.ui.Test, 因此根文件夾是com文件夾的上級文件夾).

 

◆最後, 在Java中對資源進行定位的方法有很是多種, 在Eclipse源碼中還有例如如下一段定位文件資源的代碼, 尚未時間研究, 之後再談:

ProtectionDomain domain = Main.class.getProtectionDomain();

CodeSource source = null;

URL result = null;

if (domain != null)

source = domain.getCodeSource();//得到code source

if (source != null)

      result = source.getLocation();//得到URL

          

String path = decode(result.getFile());//

// normalize to not have leading / so we can check the form

File file = new File(path);

path = file.toString().replace('""', '/');

// create a file URL (via File) to normalize the form (e.g., put

// the leading / on if necessary)

path = new File(path).toURL().getFile();

 

 

剛纔試了一下,發現假設類路徑上有反覆的資源,getResource()方法會返回類路徑上碰到的第一個資源。 而getResources()則會返回當前類載入器路徑上的所有反覆資源以及父類載入器上的所有反覆資源。 比方,在tomcat/lib文件夾下放置一個zip文件,包括config/aaa.txt文件, 在WEB-INF/lib文件夾下複製一份這個zip文件, 再在src文件夾下放上config/aaa.txt文件, getResource("config/aaa.txt")返回結果是: file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/classes/config/aaa.txt getResources("config/aaa.txt")返回結果是: file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/classes/config/aaa.txt jar:file:/D:/apache-tomcat-6.0.16/lib/aaaaa.jar!/config/aaa.txt jar:file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/lib/bbbbb.jar!/config/aaa.txt 

相關文章
相關標籤/搜索