jar包讀取file的時(shí)候相對(duì)和絕對(duì)路徑的問(wèn)題_第1頁(yè)
jar包讀取file的時(shí)候相對(duì)和絕對(duì)路徑的問(wèn)題_第2頁(yè)
jar包讀取file的時(shí)候相對(duì)和絕對(duì)路徑的問(wèn)題_第3頁(yè)
jar包讀取file的時(shí)候相對(duì)和絕對(duì)路徑的問(wèn)題_第4頁(yè)
jar包讀取file的時(shí)候相對(duì)和絕對(duì)路徑的問(wèn)題_第5頁(yè)
已閱讀5頁(yè),還剩7頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、我們常常在代碼中讀取一些資源文件(比如圖片,音樂(lè),文本等等)。在單獨(dú)運(yùn)行的時(shí)候這些簡(jiǎn)單的處理當(dāng)然不會(huì)有問(wèn)題。但是,如果我們把代碼打成一個(gè)jar包以后,即使將資源文件一并打包,這些東西也找不出來(lái)了??纯聪旅娴拇a:Java代碼1. /源代碼1:2. packageedu.hxraid; 3. importjava.io.*; 4. publicclassResource 5. publicvoidgetResource()throwsIOException 6. Filefile=newFile(bin/resource/res.txt); 7. BufferedReaderbr=newBuff

2、eredReader(newFileReader(file); 8. Strings=; 9. while(s=br.readLine()!=null) 10. System.out.println(s); 11. 12. javaview plaincopy1. /源代碼1:2. packageedu.hxraid;3. importjava.io.*;4. publicclassResource5. publicvoidgetResource()throwsIOException6. Filefile=newFile(bin/resource/res.txt);7. BufferedRea

3、derbr=newBufferedReader(newFileReader(file);8. Strings=;9. while(s=br.readLine()!=null)10. System.out.println(s);11. 12. 這段代碼寫(xiě)在Eclipse建立的java Project中,其目錄為:(其中將資源文件res.txt放在了bin目錄下,以便打成jar包) 1、src/ src/edu/hxraid/Resource.java 2、bin/ bin/resource/res.txt bin/edu/hxraid/Resource.class 很顯然運(yùn)行源代碼1是能夠找到資

4、源文件res.txt。但當(dāng)我們把整個(gè)工程打成jar包以后(ResourceJar.jar),這個(gè)jar包內(nèi)的目錄為: edu/hxraid/Resource.class resource/res.txt而這時(shí)jar包中Resource.class字節(jié)碼:ldc 20 將無(wú)法定位到j(luò)ar包中的res.txt位置上。就算把bin/目錄去掉:ldc 20 仍然無(wú)法定位到j(luò)ar包中res.txt上。這主要是因?yàn)閖ar包是一個(gè)單獨(dú)的文件而非文件夾,絕對(duì)不可能通過(guò)file:/e:/./ResourceJar.jar/resource/res.txt這種形式的文件URL來(lái)定位res.txt。所以即使是相對(duì)路

5、徑,也無(wú)法定位到j(luò)ar文件內(nèi)的txt文件(讀者也許對(duì)這段原因解釋有些費(fèi)解,在下面我們會(huì)用一段代碼運(yùn)行的結(jié)果來(lái)進(jìn)一步闡述)。那么把資源打入jar包,無(wú)論ResourceJar.jar在系統(tǒng)的什么路徑下,jar包中的字節(jié)碼程序都可以找到該包中的資源。這會(huì)是幻想嗎? 當(dāng)然不是,我們可以用類(lèi)裝載器(ClassLoader)來(lái)做到這一點(diǎn): (1)ClassLoader 是類(lèi)加載器的抽象類(lèi)。它可以在運(yùn)行時(shí)動(dòng)態(tài)的獲取加載類(lèi)的運(yùn)行信息??梢赃@樣說(shuō),當(dāng)我們調(diào)用ResourceJar.jar中的Resource類(lèi)時(shí),JVM加載進(jìn)Resource類(lèi),并記錄下Resource運(yùn)行時(shí)信息(包括Resource所在jar

6、包的路徑信息)。而ClassLoader類(lèi)中的方法可以幫助我們動(dòng)態(tài)的獲取這些信息: public URL getResource(String name) 查找具有給定名稱(chēng)的資源。資源是可以通過(guò)類(lèi)代碼以與代碼基無(wú)關(guān)的方式訪問(wèn)的一些數(shù)據(jù)(圖像、聲音、文本等)。并返回資源的URL對(duì)象。 public InputStream getResourceAsStream(String name); 返回讀取指定資源的輸入流。這個(gè)方法很重要,可以直接獲得jar包中文件的內(nèi)容。(2)ClassLoader是abstract的,不可能實(shí)例化對(duì)象,更加不可能通過(guò)ClassLoader調(diào)用上面兩個(gè)方法。所以我們真正

7、寫(xiě)代碼的時(shí)候,是通過(guò)Class類(lèi)中的getResource()和getResourceAsStream()方法,這兩個(gè)方法會(huì)委托ClassLoader中的getResource()和getResourceAsStream()方法。好了,現(xiàn)在我們重新寫(xiě)一段Resource代碼,來(lái)看看上面那段費(fèi)解的話是什么意思了:Java代碼1. /源代碼2:2. packageedu.hxraid; 3. importjava.io.*; 4. import.URL; 5. publicclassResource 6. publicvoidgetResource()throwsIOException 7. /查

8、找指定資源的URL,其中res.txt仍然開(kāi)始的bin目錄下8. URLfileURL=this.getClass().getResource(/resource/res.txt); 9. System.out.println(fileURL.getFile(); 10. 11. publicstaticvoidmain(Stringargs)throwsIOException 12. Resourceres=newResource(); 13. res.getResource(); 14. 15. javaview plaincopy1. /源代碼2:2. packageedu.hxraid

9、;3. importjava.io.*;4. import.URL;5. publicclassResource6. publicvoidgetResource()throwsIOException7. /查找指定資源的URL,其中res.txt仍然開(kāi)始的bin目錄下8. URLfileURL=this.getClass().getResource(/resource/res.txt);9. System.out.println(fileURL.getFile();10. 11. publicstaticvoidmain(Stringargs)throwsIOException12. Reso

10、urceres=newResource();13. res.getResource();14. 15. 運(yùn)行這段源代碼結(jié)果:/E:/Code_Factory/WANWAN/bin/resource/res.txt(./Code_Factory/WANWAN/.是java project所在的路徑)我們將這段代碼打包成ResourceJar.jar ,并將ResourceJar.jar放在其他路徑下(比如 c:ResourceJar.jar)。然后另外創(chuàng)建一個(gè)java project并導(dǎo)入ResourceJar.jar,寫(xiě)一段調(diào)用jar包中Resource類(lèi)的測(cè)試代碼:Java代碼1. impo

11、rtjava.io.IOException; 2. importedu.hxraid.Resource; 3. publicclassTEST 4. publicstaticvoidmain(Stringargs)throwsIOException 5. Resourceres=newResource(); 6. res.getResource(); 7. 8. javaview plaincopy1. importjava.io.IOException;2. importedu.hxraid.Resource;3. publicclassTEST4. publicstaticvoidmain

12、(Stringargs)throwsIOException5. Resourceres=newResource();6. res.getResource();7. 8. 這時(shí)的運(yùn)行結(jié)果是:file:/C:/ResourceJar.jar!/resource/res.txt我們成功的在運(yùn)行時(shí)動(dòng)態(tài)獲得了res.txt的位置。然而,問(wèn)題來(lái)了,你是否可以通過(guò)下面這樣的代碼來(lái)得到res.txt文件? File f=new File(C:/ResourceJar.jar!/resource/res.txt); 當(dāng)然不可能,因?yàn)?/ResourceJar.jar!/resource/.并不是文件資源定位符的

13、格式 (jar中資源有其專(zhuān)門(mén)的URL形式:jar:!/entry)。所以,如果jar包中的類(lèi)源代碼用File f=new File(相對(duì)路徑);的形式,是不可能定位到文件資源的。這也是為什么源代碼1打包成jar文件后,調(diào)用jar包時(shí)會(huì)報(bào)出FileNotFoundException的癥結(jié)所在了。(3)我們不能用常規(guī)操作文件的方法來(lái)讀取ResourceJar.jar中的資源文件res.txt,但可以通過(guò)Class類(lèi)的getResourceAsStream()方法來(lái)獲取,這種方法是如何讀取jar中的資源文件的,這一點(diǎn)對(duì)于我們來(lái)說(shuō)是透明的。我們將Resource.java改寫(xiě)成:Java代碼1. /源

14、代碼3:2. packageedu.hxraid; 3. importjava.io.*; 4. publicclassResource 5. publicvoidgetResource()throwsIOException 6. /返回讀取指定資源的輸入流7. InputStreamis=this.getClass().getResourceAsStream(/resource/res.txt); 8. BufferedReaderbr=newBufferedReader(newInputStreamReader(is); 9. Strings=; 10. while(s=br.readLi

15、ne()!=null) 11. System.out.println(s); 12. 13. javaview plaincopy1. /源代碼3:2. packageedu.hxraid;3. importjava.io.*;4. publicclassResource5. publicvoidgetResource()throwsIOException6. /返回讀取指定資源的輸入流7. InputStreamis=this.getClass().getResourceAsStream(/resource/res.txt);8. BufferedReaderbr=newBufferedRe

16、ader(newInputStreamReader(is);9. Strings=;10. while(s=br.readLine()!=null)11. System.out.println(s);12. 13. 我們將java工程下/bin目錄中的edu/hxraid/Resource.class和資源文件resource/res.txt一并打包進(jìn)ResourceJar.jar中,不管jar包在系統(tǒng)的任何目錄下,調(diào)用jar包中的Resource類(lèi)都可以獲得jar包中的res.txt資源,再也不會(huì)找不到res.txt文件了這里分為具體兩種:第一種:資源文件為一般后綴文件第二種:資源文件為圖片

17、文件【NO1】第一種 使用這行代碼可以獲取class類(lèi)的根目錄的路徑 String path =Thread.currentThread().getContextClassLoader().getResource().getPath();例子:我用的開(kāi)發(fā)軟件MyEclipse 6.5假設(shè)項(xiàng)目文件夾如下: filesbincore(生成class包) | | |Main.class(生成的class文件) | | | |resource( 生成資源文件夾) | |a.bat | |b.png |srccore(源包) | | Main.java(源代碼) | |resource(源資源文件夾)

18、|a.bat |b.png/源代碼Main.java/=package core;import java.io.File;public class Main public static void main(String args) try String path = Thread.currentThread().getContextClassLoader().getResource().getPath(); /添加 File af=new File(path+/resource); if(!af.exists() System.out.println(nullEXIST); String fi

19、les =af.list(); if(files.length=0) System.out.println(nullLENGTH); for(int i=0;ifiles.length;i+) if(filesi!=null)System.out.println(filesi); else System.out.println(null); catch(Exception e) System.out.println(HugeERROR); / = 運(yùn)行結(jié)果:a.batb.png就對(duì)了【NO2】第二種建議使用下面( 2 )方法,因?yàn)椋?)jar之后可能出現(xiàn)找不到的問(wèn)題 (之前我試過(guò)出現(xiàn)這種情況)

20、這里代碼省了(1)、你將所有資源打包為epm.jar,你的類(lèi)位于一個(gè)包中:package core;你的圖片資源全部放在images文件夾中,而images文件夾也位于core包內(nèi)。這樣的話,最終的路徑表現(xiàn)為:epmbincore(生成class包) | | |Main.class(生成的class文件) | | | |images( 生成資源文件夾) | |system.bat | |background.png |srccore(源包) | | Main.java(源代碼) | |images(源資源文件夾) |system.bat |background.png 可以通過(guò)相對(duì)路徑來(lái)訪問(wèn):

21、 .URL imUrl = getClass().getResource(images/background.png); ImageIcon im = new ImageIcon(imUrl);(2)、另一種情況,如果你的類(lèi)有很多,并且包的結(jié)構(gòu)很復(fù)雜,應(yīng)該把圖片放到最外層,讓所有的類(lèi)通過(guò)絕對(duì)路徑來(lái)訪問(wèn)該圖片epmbincore(生成class包) | | |Main.class(生成的class文件) | | | |images( 生成資源文件夾) | |system.bat | |background.png |srccore(源包) | | Main.java(源代碼) | |images

22、(源資源文件夾) |system.bat |background.png.URL imUrl = getClass().getResource(/images/background.png);ImageIcon im = new ImageIcon(imgUrl);區(qū)別非常細(xì)微,僅僅是在“images”的前面加了一個(gè)反斜杠/,這個(gè)反斜杠就表示根目錄,沒(méi)有反斜杠就表示相對(duì)路徑。Java中獲取資源文件新建一個(gè)Java工程,新建一個(gè)perties資源文件Java代碼1. userName=snail2. age=243. password=123456然后我們?cè)俳⒁粋€(gè)類(lèi)C

23、onstans.java,附上靜態(tài)變量Java代碼1. packagetestproperties;2. 3. publicclassConstants4. 5. publicstaticStringuserName;6. publicstaticintage;7. publicstaticStringpassword;8. 接下來(lái)的工作就嘗試著如何獲取properties文件類(lèi)定義的姓名、年齡和密碼了,新建一個(gè)InitProperties類(lèi)javaview plaincopy1. packagetestproperties;2. 3. importjava.io.FileInputStrea

24、m;4. importjava.io.IOException;5. importjava.util.Properties;6. 7. publicclassInitProperties8. privatestaticfinallongserialVersionUID=-2106230733190196852L;9. 10. publicvoidinit()11. 12. System.out.println(#加載配置信息#);13. Propertiesprop=newProperties();14. 15. /得到的是編譯后的bin的目錄Class.class.getClass().get

25、Resource(/).getPath();16. 17. /這個(gè)是絕對(duì)路徑18. /Stringfilepath=E:myeclipse6workspaceXXXperties;19. 20. Stringfilepath=Class.class.getClass().getResource(/).getPath()+/testproperties/perties;21. 22. System.out.println(+Class.class.getClass().getResource(/).getPat

26、h()+);23. 24. FileInputStreamfis=null;25. try26. fis=newFileInputStream(filepath);27. prop.load(fis);28. Constants.userName=prop.getProperty(userName);29. Constants.age=Integer.parseInt(prop.getProperty(age);30. Constants.password=prop.getProperty(password);31. System.out.println(Constants.userName+Constants.age+Constants.password);32. System.out.println(#加載配置信息完成#);33. 34. catch(IOExceptione)35. System.out.println(加載perties文件失敗,文件不存在后者路徑不正確!);36. e.printStackTrace();37. 38. 39. publicstaticvoidmain(Stringargs

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論