java讀取文件的兩種方法:java.io和java.lang.ClassLoader
什么時(shí)候使用java.io,什么時(shí)候使用java.lang.ClassLoader呢?
(注:要是之前讀xml文件時(shí)清晰知道java讀取文件有這兩種方法就好了!可以少走很多去理解相對路徑
的彎路?。?br>
自己的總結:
*java.io:相對于當前用戶(hù)目錄的相對路徑讀??;注重與磁盤(pán)文件打交道或者純java project中使用。
(雖然ClassLoader方式更通用,但是如果不是javaEE環(huán)境,要定位到classpath路徑下去讀文件是不合理
的。)
*java.lang.ClassLoader:相對于classpath的相對路徑讀??;建議在javaEE環(huán)境中都使用這種方式。
整理資料一:http://www.code168.com/bbs/html/2005-12-9/23554625833.html
問(wèn):
java打成jar包的后續問(wèn)題?。。?!如何在讀取jar包里面的配置文件?
答1:
如果用java.util.ResourceBundle就不用擔心什么,它本來(lái)就是從class loader folder/jar文件里找
properties文件。
如果你已經(jīng)注意到了,java取文件有兩種方法,java.util.io和java.lang.ClassLoader兩種。
java.io:
File file = new File("...");
FileInputStream fis = new FileInputStream("...");
FileReader fr = new FileReader("...");
ClassLoader:
ClassLoader loader = XXXClass.class.getClassLoader();
or
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource("...");
File file = new File(url.getFile());
InputStream input = loader.getResourceAsStream("...");
這兩種,一種是從project loader folder取,一種是從class loader folder取,class loader
folder包括jar文件。
我想你應該明白了吧?自己寫(xiě)個(gè)程序test一下就知道了。
答2:
File file = new File(url.getFile());不是用在你這種情況的。
一般情況既然classloader已經(jīng)拿到resource,就沒(méi)有必要畫(huà)蛇添足地再轉成File.
轉成File事實(shí)上是為了拿到絕對路徑,我們碰到過(guò)這么一種情況。
一個(gè)Web application,用tomcat啟動(dòng),tomcat會(huì )建一個(gè)application folder,folder下面有一個(gè)web-inf
folder,再下面是classes目錄,classes目錄下面是所有的java classes.程序需要用一個(gè)property文件
記錄數據,用io package只能定位到絕對路徑,用class loader可以是相對路徑,不管tomcat在客戶(hù)電
腦上任何位置,但是,如果寫(xiě)文件在classes folder下面,tomcat會(huì )reload web server,頁(yè)面會(huì )重載
。為了定位到application folder,與web-inf并列,先用classloader,再轉成file拿到全路徑,去掉后
面不需要的folder,就可以拿到 tomecat建的web application的絕對路徑。
與你的情況不同的是,classloader定位到的文件,不在jar里頭。我認為用java io不可以定到j(luò )ar里面
。
整理資料二:
Java路徑問(wèn)題最終解決方案
http://www.matrix.org.cn/thread.shtml?topicId=6d0bbeed-9157-11db-ab77-
2bbe780ebfbf&forumId=19
一、相對于當前用戶(hù)目錄的相對路徑
就是相對于System.getProperty("user.dir")返回的路徑。
對于一般項目,這是項目的根路徑。對于JavaEE服務(wù)器,這可能是服務(wù)器的某個(gè)路徑。這個(gè)并沒(méi)有統一的
規范!
所以,絕對不要使用“相對于當前用戶(hù)目錄的相對路徑”。然而:
默認情況下,java.io 包中的類(lèi)總是根據當前用戶(hù)目錄來(lái)分析相對路徑名。此目錄由系統屬性 user.dir
指定,通常是 Java 虛擬機的調用目錄。
這就是說(shuō),在使用java.io包中的類(lèi)時(shí),最好不要使用相對路徑。否則,雖然在J2SE應用程序中可能還算
正常,但是到了J2EE程序中,一定會(huì )出問(wèn)題!而且這個(gè)路徑,在不同的服務(wù)器中都是不同的!
二、相對于classpath的相對路徑
如:相對于
file:/D:/java/eclipse32/workspace/jbpmtest3/bin/這個(gè)路徑的相對路徑。其中,bin是本項目的
classpath。所有的Java源文件編譯后的.class文件復制到這個(gè)目錄中。
三、相對路徑最佳實(shí)踐
推薦使用相對于當前classpath的相對路徑
因此,我們在使用相對路徑時(shí),應當使用相對于當前classpath的相對路徑。
ClassLoader類(lèi)的getResource(String name),getResourceAsStream(String name)等方法,使用相對于當
前項目的classpath的相對路徑來(lái)查找資源。
讀取屬性文件常用到的ResourceBundle類(lèi)的getBundle(String path)也是如此。
通過(guò)查看ClassLoader類(lèi)及其相關(guān)類(lèi)的源代碼,我發(fā)現,它實(shí)際上還是使用了URI形式的絕對路徑。通過(guò)得
到當前classpath的URI形式的絕對路徑,構建了相對路徑的URI形式的絕對路徑。(這個(gè)實(shí)際上是猜想,
因為JDK內部調用了SUN的源代碼,而這些代碼不屬于JDK,不是開(kāi)源的。)
四、相對路徑本質(zhì)上還是絕對路徑
因此,歸根結底,Java本質(zhì)上只能使用絕對路徑來(lái)尋找資源。所有的相對路徑尋找資源的方法,都不過(guò)是
一些便利方法。不過(guò)是API在底層幫助我們構建了絕對路徑,從而找到資源的!

