總結一下java獲取路徑幾種途徑
在寫java程式時不可避免要獲取檔案的路徑...總結一下,遺漏的隨時補上
1.可以在servlet的init方法裡
String path = getServletContext().getRealPath("/");
這將獲取web專案的全路徑
例如 :E:/eclipseM9/workspace/tree/
tree是我web專案的根目錄
2.你也可以隨時在任意的class裡呼叫
this.getClass().getClassLoader().getResource("/").getPath();
這將獲取 到classes目錄的全路徑
例如 : E:/eclipseM9/workspace/tree/WEB-INF/classes/
這個方法也可以不在web環境裡確定路徑,比較好用
3.request.getContextPath();
獲得web根的上下文環境
如 /tree
tree是我的web專案的root context
獲取web專案的全路徑
Java路徑問題最終解決方案
—可定位所有資源的相對路徑定址
前言
Java的路徑問題,非常難搞。最近的工作涉及到建立和讀取檔案的工作,這裡我就給大家徹底得解決
我編寫了一個方法,比ClassLoader.getResource(String 相對路徑)方法的能力更強。它可以接受“../”這樣的引數,允許我們用相對路徑來定位classpath外面的資源。這樣,我們就可以使用相對於classpath的路徑,定位所有位置的資源!
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應用程式時一般所採取的策略。
通用的相對路徑解決辦法
Java中各種相對路徑非常多,不容易使用,非常容易出錯。因此,我編寫了一個便利方法,幫助更容易的解決相對路徑問題。
Web應用程式中使用JavaSE執行的資源定址問題
在JavaSE程式中,我們一般使用classpath來作為存放資源的目的地。但是,在Web應用程式中,我們一般使用classpath外面的WEB-INF及其子目錄作為資原始檔的存放地。
在Web應用程式中,我們一般通過ServletContext.getRealPath("/")方法得到Web應用程式的根目錄的絕對路徑。這樣,我們只需要提供相對於Web應用程式根目錄的路徑,就可以構建出定位資源的絕對路徑。
Web應用程式,可以作為Web應用程式進行釋出和執行。但是,我們也常常會以JavaSE的方式來執行Web應用程式的某個類的main方法。或者,使用JUnit測試。這都需要使用JavaSE的方式來執行。
這樣,我們就無法使用ServletContext.getRealPath("/")方法得到Web應用程式的根目錄的絕對路徑。
而JDK提供的ClassLoader類,
它的getResource(String name),getResourceAsStream(String
name)
等方法,使用相對於當前專案的classpath的相對路徑來查詢資源。
讀取屬性檔案常用到的ResourceBundle類的getBundle(String path)也是如此。
它們都只能使用相對路徑來讀取classpath下的資源,無法定位到classpath外面的資源。
Classpath外配置檔案讀取問題
如,我們使用測試驅動開發的方法,開發Spring、Hibernate、iBatis等使用配置檔案的Web應用程式,就會遇到問題。
儘管Spring自己提供了FileSystem(也就是相對於user,dir目錄)來讀取Web配置檔案的方法,但是終究不是很方便。而且與Web程式中的程式碼使用方式不一致!
至於Hibernate,iBatis就更麻煩了!只有把配置檔案移到classpath下,否則根本不可能使用測試驅動開發!
這怎麼辦?
通用的相對路徑解決辦法
面對這個問題,我決定編寫一個助手類ClassLoaderUtil,提供一個便利方法[public static URL getExtendResource(String relativePath)]。在Web應用程式等一切Java程式中,需要定位classpath外的資源時,都使用這個助手類的便利方法,而不使用Web應用程式特有的ServletContext.getRealPath("/")方法來定位資源。
利用classpath的絕對路徑,定位所有資源
這個便利方法的實現原理,就是“利用classpath的絕對路徑,定位所有資源”。
ClassLoader類的getResource("")方法能夠得到當前classpath的絕對路徑,這是所有Java程式都擁有的能力,具有最大的適應性!
而目前的JDK提供的ClassLoader類的getResource(String 相對路徑)方法,只能接受一般的相對路徑。這樣,使用ClassLoader類的getResource(String 相對路徑)方法就只能定位到classpath下的資源。
如果,它能夠接受“../”這樣的引數,允許我們用相對路徑來定位classpath外面的資源,那麼我們就可以定位位置的資源!
當然,我無法修改ClassLoader類的這個方法,於是,我編寫了一個助手類ClassLoaderUtil類,提供了[public static URL getExtendResource(String relativePath)]這個方法。它能夠接受帶有“../”符號的相對路徑,實現了自由尋找資源的功能。
通過相對classpath路徑實現自由尋找資源的助手類的原始碼:
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*@author沈東良[email protected]
*Nov29,200610:34:34AM
*用來載入類,classpath下的資原始檔,屬性檔案等。
*getExtendResource(StringrelativePath)方法,可以使用../符號來載入classpath外部的資源。
*/
publicclass ClassLoaderUtil {
privatestatic Log log=LogFactory.getLog(ClassLoaderUtil.class);
/**
*Thread.currentThread().getContextClassLoader().getResource("")
*/
/**
*載入Java類。使用全限定類名
*@paramclassName
*@return
*/
publicstatic Class loadClass(String className) {
try {
return getClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
thrownew RuntimeException("class not found '"+className+"'", e);
}
}
/**
*得到類載入器
*@return
*/
publicstatic ClassLoader getClassLoader() {
return ClassLoaderUtil.class.getClassLoader();
}
/**
*提供相對於classpath的資源路徑,返回檔案的輸入流
*@paramrelativePath必須傳遞資源的相對路徑。是相對於classpath的路徑。如果需要查詢classpath外部的資源,需要使用../來查詢
*@return檔案輸入流
*@throwsIOException
*@throwsMalformedURLException
*/
publicstatic InputStream getStream(String relativePath) throws MalformedURLException, IOException {
if(!relativePath.contains("../")){
return getClassLoader().getResourceAsStream(relativePath);
}else{
return ClassLoaderUtil.getStreamByExtendResource(relativePath);
}
}
/**
*
*@paramurl
*@return
*@throwsIOException
*/
publicstatic InputStream getStream(URL url) throws IOException{
if(url!=null){
return url.openStream();
}else{
returnnull;
}
}
/**
*
*@paramrelativePath必須傳遞資源的相對路徑。是相對於classpath的路徑。如果需要查詢classpath外部的資源,需要使用../來查詢
*@return
*@throwsMalformedURLException
*@throwsIOException
*/
publicstatic InputStream getStreamByExtendResource(String relativePath) throws MalformedURLException, IOException{
return ClassLoaderUtil.getStream(ClassLoaderUtil.getExtendResource(relativePath));
}
/**
*提供相對於classpath的資源路徑,返回屬性物件,它是一個散列表
*@paramresource
*@return
*/
publicstatic Properties getProperties(String resource) {
Properties properties = new Properties();
try {
properties.load(getStream(resource));
} catch (IOException e) {
thrownew RuntimeException("couldn't load properties file '"+resource+"'", e);
}
return properties;
}
/**
*得到本Class所在的ClassLoader的Classpat的絕對路徑。
*URL形式的
*@return
*/
publicstatic String getAbsolutePathOfClassLoaderClassPath(){
ClassLoaderUtil.log.info(ClassLoaderUtil.getClassLoader().getResource("").toString());
return ClassLoaderUtil.getClassLoader().getResource("").toString();
}
/**
*
*@paramrelativePath必須傳遞資源的相對路徑。是相對於classpath的路徑。如果需要查詢classpath外部的資源,需要使用../來查詢
*@return資源的絕對URL
*@throwsMalformedURLException
*/
publicstatic URL getExtendResource(String relativePath) throws MalformedURLException{
ClassLoaderUtil.log.info("傳入的相對路徑:"+relativePath) ;
//ClassLoaderUtil.log.info(Integer.valueOf(relativePath.indexOf("../"))) ;
if(!relativePath.contains("../")){
return ClassLoaderUtil.getResource(relativePath);
}
String classPathAbsolutePath=ClassLoaderUtil.getAbsolutePathOfClassLoaderClassPath();
if(relativePath.substring(0, 1).equals("/")){
relativePath=relativePath.substring(1);
}
ClassLoaderUtil.log.info(Integer.valueOf(relativePath.lastIndexOf("../"))) ;
String wildcardString=relativePath.substring(0,relativePath.lastIndexOf("../")+3);
relativePath=relativePath.substring(relativePath.lastIndexOf("../")+3);
int containSum=ClassLoaderUtil.containSum(wildcardString, "../");
classPathAbsolutePath= ClassLoaderUtil.cutLastString(classPathAbsolutePath, "/", containSum);
String resourceAbsolutePath=classPathAbsolutePath+relativePath;
ClassLoaderUtil.log.info("絕對路徑:"+resourceAbsolutePath) ;
URL resourceAbsoluteURL=new URL(resourceAbsolutePath);
return resourceAbsoluteURL;
}
/**
*
*@paramsource
*@paramdest
*@return
*/
privatestaticint containSum(String source,String dest){
int containSum=0;
int destLength=dest.length();
while(source.contains(dest)){
containSum=containSum+1;
source=source.substring(destLength);
}
return containSum;
}
/**
*
*@paramsource
*@paramdest
*@paramnum
*@return
*/
privatestatic String cutLastString(String source,String dest,int num){
// String cutSource=null;
for(int i=0;i<NUM;I++){< span="" />
source=source.substring(0, source.lastIndexOf(dest, source.length()-2)+1);
}
return source;
}
/**
*
*@paramresource
*@return
*/
publicstatic URL getResource(String resource){
ClassLoaderUtil.log.info("傳入的相對於classpath的路徑:"+resource) ;
return ClassLoaderUtil.getClassLoader().getResource(resource);
}
/**
*@paramargs
*@throwsMalformedURLException
*/
publicstaticvoid main(String[] args) throws MalformedURLException {
//ClassLoaderUtil.getExtendResource("../spring/dao.xml");
//ClassLoaderUtil.getExtendResource("../../../src/log4j.properties");
ClassLoaderUtil.getExtendResource("log4j.properties");
System.out.println(ClassLoaderUtil.getClassLoader().getResource("log4j.properties").toString());
}
}
相關推薦
總結一下java獲取路徑幾種途徑
在寫java程式時不可避免要獲取檔案的路徑...總結一下,遺漏的隨時補上 1.可以在servlet的init方法裡 String path = getServletContext().getRealPath("/"); 這將獲取web專案的全路徑 例如 :E:/eclipseM9/workspace/t
C# 獲取路徑幾種方式
// 獲取程式的基目錄。 System.AppDomain.CurrentDomain.BaseDirectory // 獲取模組的完整路徑。 System.Diagnostics.Process.GetCurrentProcess().MainModule.FileNa
Java獲取路徑的幾種方式
private static String FILE_NAME = "zxl.txt"; 第一種 new ClassPathResource(檔名) ClassPathResource classPathResource = new ClassPathResource(FI
java(JSP)中幾種獲取專案路徑方式
struts2設定了struts.multipart.saveDir後會在根目錄建立資料夾,這樣會涉及linux下的許可權問題, 最好不要設定,使用struts預設 需要使用路徑時,用下面的方法取得專案根目錄的絕對路徑(Tools為方法類) public static String getRootP
java ----獲取路徑的各種方法(總結)
Java Web開發中路徑問題小結 (1) Web開發中路徑的幾個基本概念 假設在瀏覽器中訪問了如下的頁面,如圖1所示: 那麼針對這個站點的幾個基本概念表述如下: 二.幾個路徑相關函式的返回值: 在TestURL.jsp檔案中測試了三個路徑相關函式:
java的list幾種實現方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java時間戳的三種獲取方式比較
一、list簡介 List列表類,順序儲存任何物件(順序不變),可重複。 List是繼承於Collection的介面,不能例項化。例項化可以用: ArrayList(實現動態陣列),查詢快(隨
GridView控制元件RowDataBound事件中獲取列欄位值的幾種途徑 !!!
protectedvoid GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) {
GridView控制元件RowDataBound事件中獲取列欄位的幾種途徑
GridView是ASP.NET中功能強大的資料顯示控制元件,它的RowDataBound事件為我們提供了方便的控制行、列資料的途徑。要獲取當前行的某個資料列,我在實踐中總結有如下幾種方法:1. Cells[x].Txt。 從列單元格的文字值獲取。這種方法簡單高率,最為
Java Map的幾種迴圈方式學習總結
1:根據JDK的新特性,用For迴圈Map,例如迴圈Map的Key Map<Object , Object> map = new HashMap<Object, Object>
vs中獲取當前exe檔案執行路徑幾種方法
1、 TCHAR szFilePath[MAX_PATH + 1]; GetModuleFileName(NULL, szFilePath, MAX_PATH); (_tcsrchr(szFilePath, _T('//')))[1] = 0;//刪除檔名,只獲得路
java獲取路徑,檔名的方法總結
1. 檔案路徑獲取 Thread.currentThread().getContextClassLoader().getResource(“”) //獲得資原始檔(.class檔案)所在路徑 ClassLoader.getSystemResource(“”)
java中的幾種對象(PO,VO,DAO,BO,POJO)
objects 其中 標準 setter ant object get 組件 工廠類 一、PO :(persistant object ),持久對象 可以看成是與數據庫中的表相映射的java對象。使用Hibernate來生成PO是不錯的選擇。二、VO :(value ob
java基礎之幾種常見的排序算法
java基礎 csdn n) min center 最小 fill 順序 system 一,冒泡排序 1、原理: 從數組的第一個位置開始兩兩比較array[index]和array[index+1],如果array[index]大於array[index+1]則交換a
Spring 獲取bean 幾種方式
讀取 獲取 static ava ade beans java ride .html 轉載自: http://www.cnblogs.com/luoluoshidafu/p/5659574.html 1.讀取xml文件的方式,這種在初學入門的時候比較適用 。 A
Spring3 MVC請求參數獲取的幾種方法
setup return 異常 pathvaria method let 方法 ces 解決 一、 [email protected]/* */ @RequestMapping(value="user/{id}/{name}",method=Requ
java常見的幾種設計模式
設計模式 單例 餓漢式 懶漢式 設計模式 1、概述 1)設計模式(Design pattern):是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結; 2)分類: 創建型模式(創建對象的): 單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 行為型模式(對象
Java常見的幾種內存溢出及解決方案
-xmx 系列 lba pan fff 特征 聚類算法 聲明 space 1.JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap space JVM在啟動的時候會自動設置JVM Heap的值, 可以利用JVM提
【轉載】java 獲取路徑的各種方法
strong filepath 文件路徑 etc dex 讀取 workspace for class 轉載只供個人學習參考,查看請前往原出處:http://www.cnblogs.com/guoyuqiangf8/p/3506768.html 主要方法有: (1)、req
Java常用的幾種線程池
fin cep read out fixed 重新 stat 支持 con 常用的幾種線程池 5.1 newCachedThreadPool 創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。 這種類型的線程池特點是: 工作線程
HDU 1576 -- A/B (總結乘法逆元的幾種求法)
推廣 ont show 乘法逆元 ostream space 同余 乘法 個數 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)