1. 程式人生 > >總結一下java獲取路徑幾種途徑

總結一下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的路徑問題,非常難搞。最近的工作涉及到建立和讀取檔案的工作,這裡我就給大家徹底得解決

Java路徑問題。

我編寫了一個方法,比ClassLoader.getResource(String 相對路徑)方法的能力更強。它可以接受“../”這樣的引數,允許我們用相對路徑來定位classpath外面的資源。這樣,我們就可以使用相對於classpath的路徑,定位所有位置的資源!

Java路徑

Java中使用的路徑,分為兩種:絕對路徑和相對路徑。具體而言,又分為四種:

一、URI形式的絕對資源路徑

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

URLURI的特例。URL的字首/協議,必須是Java認識的。URL可以開啟資源,而URI則不行。

URLURI物件可以互相轉換,使用各自的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形式的絕對路徑。通過得到當前classpathURI形式的絕對路徑,構建了相對路徑的URI形式的絕對路徑。(這個實際上是猜想,因為JDK內部呼叫了SUN的原始碼,而這些程式碼不屬於JDK,不是開源的。)

相對路徑本質上還是絕對路徑

因此,歸根結底,Java本質上只能使用絕對路徑來尋找資源。所有的相對路徑尋找資源的方法,都不過是一些便利方法。不過是API在底層幫助我們構建了絕對路徑,從而找到資源的!

得到classpath和當前類的絕對路徑的一些方法

下面是一些得到classpath和當前類的絕對路徑的一些方法。你可能需要使用其中的一些方法來得到你需要的資源的絕對路徑。

1FileTest.class.getResource("")

得到的是當前類FileTest.class檔案的URI目錄。不包括自己!

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/

2FileTest.class.getResource("/")

得到的是當前的classpath的絕對URI路徑。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

3Thread.currentThread().getContextClassLoader().getResource("")

得到的也是當前ClassPath的絕對URI路徑。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

4FileTest.class.getClassLoader().getResource("")

得到的也是當前ClassPath的絕對URI路徑。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

5ClassLoader.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外配置檔案讀取問題

如,我們使用測試驅動開發的方法,開發SpringHibernateiBatis等使用配置檔案的Web應用程式,就會遇到問題。

儘管Spring自己提供了FileSystem(也就是相對於user,dir目錄)來讀取Web配置檔案的方法,但是終究不是很方便。而且與Web程式中的程式碼使用方式不一致!

至於HibernateiBatis就更麻煩了!只有把配置檔案移到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所在的ClassLoaderClasspat的絕對路徑。

*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)