classloader.getresources()介紹

◆一般情況下,我們都使用相對路徑來獲取資源,這樣的靈活性比較大.

比如當前類爲com/bbebfe/Test.class

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

而如果這些圖像資源放置在icons目錄下,則應該是com/bbebfe/icons/sample.gif

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

· 假設當前類爲com.bbebfe.Test

· 包所在的文件夾爲bin

String imageName = "icons/sample.gif"

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

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() 方法

該方法實際通過該ClassClass LoadergetResource()方法來獲得資源在調用ClassLoadergetResource()方法之前, Class.getResource()方法會對資源名稱做一定的處理,構建一個該資源的絕對名稱(absolutename, 大意是:

       +如果資源名稱以'/'('"u002f') 開始則資源的絕對名稱是'/'以後的部分.

              如果imageName"/icons/sample.gif", 則在這裏會變成"icons/sample.gif"

       +否則對於其他情況絕對名稱將是如下形式(給資源名稱的前面加上modified_package_name/):
             modified_package_name/resource_name (
修正的包名稱/資源名稱)

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

如果ClassLoader.getResource()方法返回一個值爲nullURL, Class.getResource()方法最終會將資源請求交給ClassLoader.getSystemResource(java.lang.String).

· ClassLoader.getResource() 方法

該對資源進行查找資源的名稱是以'/'分隔的路徑這個方法首先查找自己的父親ClassLoader,由自己的父ClassLoader來查找資源(實際上如果父親的父親不是空則父親仍會向上提交查找請求). 如果自己的父ClassLoadernull, 則查找Java虛擬機中內建的classloader, 並將資源請求提交給它們如果這些操作都失敗了ClassLoader會調用自己的findResource()方法來查找資源.

· ClassLoader.findResource() 方法

該方法在內部查找指定的資源如果你實現了自己的Class Loader,則應該重載這個方法以自己特定的方式來查找類文件和資源.

 

◆通過以上的總結, 我們可以看到三點.

1, 無論是getResource(), 還是findResource(), 這些方法都只是資源的定位方法最終都只是返回一個URL, 只是對資源的定位而已我們隨後應通過自己的方法來讀取這些資源而在ClassClassLoader中還定義的有getResourceAsStream方法該方法是getResource的增強版這裏就不介紹了.

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

       假設我的當前類在Eclipse工程Database類所在的包是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()方法舉個例子:

·某個工程有如下的包結構:

       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程序的語法是javacom.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 cancheck the form

File file = new File(path);

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

// create a file URL (via File) to normalizethe 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 


 

發佈了32 篇原創文章 · 獲贊 8 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章