在開發java程序的過程中我們經常要做的一件事就是獲取資源那麼什麼是資源呢?說白了在計算機裡那就是一堆數據只是這堆數據對我們的java程序有多種表現形式一般來說有FileURLInputStream等等而單就文件這一項就有很多種配置文件java類文件jps文件圖片cssjs文件等等面對這林林總總的資源我們在設計一個讀取資源的接口時就需要針對不同形式的資源提供方法這樣就導致我們的接口還是與實際的資源形式綁定在一起未能完全的抽象另外在java程序中資源的存放位置也是各異的有的存放在classpath中有的存放在文件系統中有的存放在web應用中而對於不同位置的資源java程序獲取這些資源的方法各有不同
A獲取classpath中的資源
Java代碼
URL url = thisgetClass()getResource(resource_name);
URL url = thisgetClass()getClassLoader()getResource(resource_name);
URL url = ThreadcurrentThread()getContextClassLoader()getResource(resource_name);
甜性澀愛下載 ?id=
那麼在jdk中為什麼又提供了三種方式來獲取classpath下的資源呢?這其中是有些來頭的
第一行代碼中是利用Class類的實例來獲取第二行代碼是使用加載當前類的classloader來獲取看下jdk中的源代碼會發現class類的實例最後還是委托加載他的classloader來獲取資源的
Java代碼
public URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader();
if (cl==null) {
// A system class
return ClassLoadergetSystemResource(name);
}
return clgetResource(name);
}
從上面的代碼中可以看出對於資源的加載並沒有像類加載所采用的雙親委托機制而是當前類的classloader不為null的情況下先從當前類的classloader中加載資源而只有當前類的classloader為null的時候才從system classloader中去加載資源這樣可以方便我們自定義配置類覆蓋一些默認配置當然jse應用中如果沒有特別定制classloader時我們自己寫的類都是被system classloader加載的到底利用class去獲取資源和利用classloader去獲取資源有什麼區別呢?區別就在 resolveName(name)這個方法中兩種方式對於資源名稱的表示方式不同下面是一個簡單的包結構/表示類路徑的根
/
|test
|Testclass
|testtxt
|testtxt
Java代碼
// 獲取與當前類在同一個包下的資源
URL url = thisgetClass()getResource(testtxt);
// 獲取test包下的資源需加/
URL url = thisgetClass()getResource(/com/cn/test/testtxt);
// 獲取類路徑根下的資源
URL url = thisgetClass()getClassLoader()getResource(testtxt);
// 獲取包test包下的資源
URL url = thisgetClass()getResource(com/cn/test/testtxt);
而第三利用當前線程的contextClassLoader來獲取資源的解釋可以參考我的另一篇
B獲取文件系統中的資源
Java代碼
// 獲得File對象
File file = new File(testtxt);
// 獲得File對象的字節流
InputStream in = new FileInputStream(file);
值得注意的是在File的構造函數File(String name) 中的name參數可以是相對路徑和絕對路徑相對路徑是相對於SystemgetProperties(userdir)的
C獲取web應用中的資源
Java代碼
servletContextgetResourceAsStream(resource_name);
resource_names為相對於webroot的路徑表示例如獲取webxmlresource_name表示為/WEBINF/webxml
面對上面介紹的各種資源表現形式和存放位置難道java中就沒有提供一個統一處理方式嗎?有URL
從名稱上來看 URL(Uniform Resource Locator) 統一資源定位器看起來很好很強大但很多時候使用它並不能定位到我們需要的資源
首先它jdk中體統的URL能訪問的協議非常有限(當然可以進行擴展不過很麻煩)常用的有httpfileftp等等並沒有提供對classpath和servletContext中的資源的獲取方法
另外它沒有提供判斷資源是否存在的方法每次只有等我們真正去獲取資源的時候拋出異常才能知道資源無法獲取
其次URL這個類的職責未劃分清楚既用來表示資源有用來獲取其資源
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26654.html