標籤:
在Java的程式發布中,很多人會選擇採用二進位的jar的格式進行發布,怎麼樣讀取Jar裡面的資源呢?
主要是採用ClassLoader的下面幾個方法來實現:
public URL getResource(String name);
public InputStream getResourceAsStream(String name)
public static InputStream getSystemResourceAsStream(String name)
public static URL getSystemResource(String name)
我一般都是使用:
getClass().getResource(...);
比如,設定JFrame的表徵圖:
this.setIconImage(new ImageIcon(getClass().getResource(...)).getImage());
但是我今天遇到的問題是,在程式中需要播放一個存放在jar中的notify.wav音效檔,My Code:
System.out.println(getClass().getResource("/sound/notify.wav").getPath());
System.out.println(getClass().getResource("/sound/notify.wav").getFile());
System.out.println(getClass().getResource("/sound/notify.wav").toExternalForm());
System.out.println(getClass().getResource("/sound/notify.wav").toString());
/*
//輸出的路徑
/D:/soft/test/bin/sound/notify.wav
/D:/soft/test/bin/sound/notify.wav
file:/D:/soft/test/bin/sound/notify.wav
file:/D:/soft/test/bin/sound/notify.wav
*/
FileInputStream audioFIS = new FileInputStream(getClass().getResource("/sound/notify.wav").getFile());
AudioPlayer.player.start(audioFIS); //播放聲音
在eclipse中測試的時候,能正常播放聲音,但打包成jar檔案後,就提示找不到音效檔了。
為什麼在最上面的設定視窗的表徵圖時,可以,但在這裡播放jar中的音效檔時就出錯了呢?
最後通過在網上搜尋,找到這篇介紹(http://www.iteye.com/topic/483115)才明白:
摘抄一部分內容:...........................
這主要是因為jar包是一個單獨的檔案而非檔案夾,絕對不可能通過"file:/e:/.../ResourceJar.jar/resource /res.txt"這種形式的檔案URL來定位res.txt。所以即使是相對路徑,也無法定位到jar檔案內的txt檔案(讀者也許對這段原因解釋有些費解,在下面我們會用一段代碼啟動並執行結果來進一步闡述)。
因為".../ResourceJar.jar!/resource/...."並不是檔案資源定位器的格式 (jar中資源有其專門的URL形式: jar:<url>!/{entry} )。所以,如果jar包中的類原始碼用File f=new File(相對路徑);的形式,是不可能定位到檔案資源的。這也是為什麼原始碼1打包成jar檔案後,調用jar包時會報出FileNotFoundException的癥結所在了。
//解決辦法也很簡單,直接使用:getClass().getResourceAsStream()
InputStream audioIS = getClass().getResourceAsStream("/sound/notify.wav");;
AudioPlayer.player.start(audioIS);
2012-01-29
java: 關於從jar中讀取資源遇到的問題getClass().getResource(...)