1. 程式人生 > >java路徑以及獲取資原始檔的方法

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”);