java路徑以及獲取資原始檔的方法
Java路徑
Java中使用的路徑,分為兩種:絕對路徑和相對路徑。具體而言,又分為四種:
一、URI形式的絕對資源路徑
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b
URL是URI的特例。URL的字首/協議,必須是Java熟悉的。URL可以開啟資源,而URI則不行。
URL和URI物件可以互相轉換,使用各自的toURI(),toURL()方法即可!
二、本地系統的絕對路徑
D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b
Java.io包中的類,需要使用這種形式的引數。
但是,它們一般也提供了URI型別的引數,而URI型別的引數,接受的是URI樣式的String。因此,通過URI轉換,還是可以把URI樣式的絕對路徑用在java.io包中的類中。
三、相對於classpath的相對路徑
如:相對於
file:/D:/java/eclipse32/workspace/jbpmtest3/bin/這個路徑的相對路徑。其中,bin是本專案的classpath。所有的Java原始檔編譯後的.class檔案複製到這個目錄中。
四、相對於當前使用者目錄的相對路徑
就是相對於System.getProperty(“user.dir”)返回的路徑。
對於一般專案,這是專案的根路徑。對於JavaEE伺服器,這可能是伺服器的某個路徑。這個並沒有統一的規範!
所以,絕對不要使用”相對於當前使用者目錄的相對路徑”。然而:
預設情況下,java.io 包中的類總是根據當前使用者目錄來分析相對路徑名。此目錄由系統屬性 user.dir 指定,通常是 Java 虛擬機器的呼叫目錄。
這就是說,在使用java.io包中的類時,最好不要使用相對路徑。否則,雖然在J2SE應用程式中可能還算正常,但是到了J2EE程式中,一定會出問題!而且這個路徑,在不同的伺服器中都是不同的!
相對路徑最佳實踐
推薦使用相對於當前classpath的相對路徑
因此,我們在使用相對路徑時,應當使用相對於當前classpath的相對路徑。
ClassLoader類的getResource(String name),getResourceAsStream(String name)等方法,使用相對於當前專案的classpath的相對路徑來查詢資源。
讀取屬性檔案常用到的ResourceBundle類的getBundle(String path)也是如此。
通過檢視ClassLoader類及其相關類的原始碼,我發現,它實際上還是使用了URI形式的絕對路徑。通過得到當前classpath的 URI形式的絕對路徑,構建了相對路徑的URI形式的絕對路徑。(這個實際上是猜想,因為JDK內部呼叫了SUN的原始碼,而這些程式碼不屬於JDK,不是開源的。) 相對路徑本質上還是絕對路徑
因此,歸根結底,Java本質上只能使用絕對路徑來尋找資源。所有的相對路徑尋找資源的方法,都不過是一些便利方法。不過是API在底層幫助我們構建了絕對路徑,從而找到資源的!
得到classpath和當前類的絕對路徑的一些方法
下面是一些得到classpath和當前類的絕對路徑的一些方法。你可能需要使用其中的一些方法來得到你需要的資源的絕對路徑。
1.FileTest.class.getResource(“”)
得到的是當前類FileTest.class檔案的URI目錄。不包括自己!
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/
2.FileTest.class.getResource(“/”)
得到的是當前的classpath的絕對URI路徑。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
3.Thread.currentThread().getContextClassLoader().getResource(“”)
得到的也是當前ClassPath的絕對URI路徑。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
4.FileTest.class.getClassLoader().getResource(“”)
得到的也是當前ClassPath的絕對URI路徑。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
5.ClassLoader.getSystemResource(“”)
得到的也是當前ClassPath的絕對URI路徑。
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
我推薦使用Thread.currentThread().getContextClassLoader().getResource(“”)來得到當前的classpath的絕對路徑的URI表示法。
Web應用程式中資源的定址
上文中說過,當前使用者目錄,即相對於System.getProperty(“user.dir”)返回的路徑。
對於JavaEE伺服器,這可能是伺服器的某個路徑,這個並沒有統一的規範!
而不是我們釋出的Web應用程式的根目錄!
這樣,在Web應用程式中,我們絕對不能使用相對於當前使用者目錄的相對路徑。
在Web應用程式中,我們一般通過ServletContext.getRealPath(“/”)方法得到Web應用程式的根目錄的絕對路徑。
這樣,我們只需要提供相對於Web應用程式根目錄的路徑,就可以構建出定位資源的絕對路徑。
這是我們開發Web應用程式時一般所採取的策略。
推薦使用Thread.currentThread().getContextClassLoader().getResource(“”)來得到當前的classpath的絕對路徑的URI表示法。
Application可以通過new FileInputStream(“xx.properties”);直接在classes一級獲取。關鍵是有時我們需要通過web修改配置檔案,我們不 能將路徑寫死了。經過測試覺得有以下心得:
1.servlet中讀寫。如果運用Struts 或者Servlet可以直接在初始化引數中配置,呼叫時根據servlet的getRealPath(“/”)獲取真實路徑,再根據String file = this.servlet.getInitParameter(“abc”);獲取相對的WEB-INF的相對路徑。
例:
InputStream input =Thread.currentThread().getContextClassLoader().getResourceAsStream(“abc.properties”);
Properties prop = new Properties();
prop.load(input);
input.close();
prop.setProperty(“abc”, “test”);
prop.store(new FileOutputStream(path), “–test–”);
out.close();
2.直接在jsp中操作,通過jsp內建物件獲取可操作的絕對地址。
例:
// jsp頁面
String path = pageContext.getServletContext().getRealPath(“/”);
String realPath = path+”/WEB-INF/classes/abc.properties”;
//java 程式
InputStream in = getClass().getClassLoader().getResourceAsStream(“abc.properties”); // abc.properties放在webroot/WEB-INF/classes/目錄下
prop.load(in);
in.close();
OutputStream out = new FileOutputStream(path); // path為通過頁面傳入的路徑
prop.setProperty(“abc”, “abcccccc”);
prop.store(out, “–test–”);
out.close();
3.只通過Java程式操作資原始檔
InputStream in = new FileInputStream(“abc.properties”); // 相對路徑,專案下的路徑
OutputStream out = new FileOutputStream(“abc.properties”);