jungleford如是說(shuō)
可能有不少初學(xué)者會(huì)有這樣的困惑(以前我也有過(guò)):在你的代碼里調(diào)用了一些資源文件,如圖片,音樂(lè)等,在調(diào)試環(huán)境或單獨(dú)運(yùn)行的時(shí)候可以正常顯示或播放,而一旦打包到j(luò)ar文件中,這些東東就再也出不來(lái)了,除非把這個(gè)jar放到原來(lái)未打包以前的目錄下,但通常jar是單獨(dú)發(fā)布的。這里介紹一個(gè)解決這類(lèi)問(wèn)題的方法。
getResource和getResourceAsStream
問(wèn)題的根源還是在于老生常談的所謂class path,不信的話你在系統(tǒng)環(huán)境變量里的ClassPath加上你的jar文件,這下你就看得到你的圖片了!但單獨(dú)發(fā)布jar的話不可能指望每次都讓用戶為你的jar而專(zhuān)門(mén)修改classpath。那么有沒(méi)有什么辦法一勞永逸地搞定它呢?我們需要從類(lèi)的裝載入手。先扯遠(yuǎn)一點(diǎn),在開(kāi)發(fā)JSP之類(lèi)的Web應(yīng)用程序的時(shí)候要用到第三方的庫(kù)怎么辦?通常的做法是把這些庫(kù)(可以是class,也可以是jar)統(tǒng)統(tǒng)放到WEB-INF/lib/目錄下面,為什么這樣系統(tǒng)就認(rèn)了呢?因?yàn)閃eb容器(譬如Tomcat)在裝載類(lèi)的時(shí)候有自己的組織方式(可以參考Tomcat手冊(cè))。特別地,jar也是類(lèi)裝載器的一個(gè)可訪問(wèn)媒介,ClassLoader提供了兩個(gè)方法用于從裝載的類(lèi)路徑中取得資源:


這里name是資源的類(lèi)路徑,它是相對(duì)與“/”根路徑下的位置。getResource得到的是一個(gè)URL對(duì)象來(lái)定位資源,而getResourceAsStream取得該資源輸入流的引用保證程序可以從正確的位置抽取數(shù)據(jù)。
真正使用的不是ClassLoader的這兩個(gè)方法,而是Class的getResource和getResourceAsStream方法,因?yàn)镃lass對(duì)象可以從你的類(lèi)得到(如YourClass.class或YourClass.getClass()),而ClassLoader則需要再調(diào)用一次YourClass.getClassLoader()方法,但根據(jù)JDK文檔的說(shuō)法,Class對(duì)象的這兩個(gè)方法其實(shí)是“委托”(delegate)給裝載它的ClassLoader來(lái)做的,所以只需要使用Class對(duì)象的這兩個(gè)方法就可以了。
在參考資料中有一篇老外寫(xiě)的文章比較深入介紹了從jar中裝載資源的方法。
一個(gè)應(yīng)用的例子
以下是在我寫(xiě)的一個(gè)小工具M(jìn)SNHistoryCombiner中用到的一段代碼,可以從jar中裝載圖片和文本信息。譬如,你的jar中根目錄下有個(gè)img目錄,里面放有一些圖片,如img1.jpg,你可以這樣調(diào)用

注意必須這里是“/img/img1.jpg”而非“img/img1.jpg”。從jar中讀文本資源也是類(lèi)似方法調(diào)用getTextFromJar。
需要說(shuō)明的是,這段代碼也不是我原創(chuàng)的,是從一段別的代碼中經(jīng)過(guò)修改得到的,但原代碼的來(lái)源忘記了,在這里向原作者表示感謝和歉意。



































































































參考資料