Java獲取路徑的方法分析詳解(Application/Web)


1、利用System.getProperty()函數獲取當前路徑:

System.getProperty("user.dir");//user.dir用戶當前的工作目錄,輸出:D:\開發工程\GitHub\5_java_example\uritest\application,(如果想要通過此方法獲取其它系統信息,參考:http://www.cnblogs.com/EasonJim/p/6507672.html

注意:以上輸出為eclipse的application的輸出。

測試JAR(Application):

正常,輸出如下:

測試WAR(Web):

正常,輸出如下:

總結:

①在jar中得到的是這個應用程序根目錄,而且最后不帶\,沒有精確到具體哪個類。

②在war中得到的是tomcat的根目錄,沒有精確到webapps這個文件,更沒有說是哪個web項目了。而在eclipse中,得到的是eclipse所在的目錄。

 

System.getProperty("java.class.path");//java.class.path類路徑,輸出:D:\開發工程\GitHub\5_java_example\uritest\application\bin,(如果想要通過此方法獲取其它系統信息,參考:http://www.cnblogs.com/EasonJim/p/6507672.html

注意:以上輸出為eclipse的application的輸出。

測試JAR(Application):

正常,輸出如下:

測試WAR(Web):

正常,輸出如下:

總結:

①在eclipse中調試application時,得到的路徑覺得是完美,精確到了bin。但是如果導出jar包,得到的路徑確實如上所示,沒有達到目的。

②在war中得到的是tomcat中bin的jar包,如上所示,都是沒有達到目的。

 

2、使用File提供的函數獲取當前路徑:  

參考:http://www.cnblogs.com/franson-2016/p/5728280.html

     try{ 
            File directory = new File("");//設定為當前文件夾
            System.out.println(directory.getCanonicalPath());//獲取標准的路徑,輸出:D:\開發工程\GitHub\5_java_example\uritest\application 
            System.out.println(directory.getAbsolutePath());//獲取絕對路徑,輸出:D:\開發工程\GitHub\5_java_example\uritest\application 
        }catch(Exception e){}         
        /*
         * File.getCanonicalPath()和File.getAbsolutePath()大約只是對於new File(".")和new File("..")兩種路徑有所區別。
         * 對於getCanonicalPath()函數,“."就表示當前的文件夾,而”..“則表示當前文件夾的上一級文件夾
         * 對於getAbsolutePath()函數,則不管”.”、“..”,返回當前的路徑加上你在new File()時設定的路徑
         * 至於getPath()函數,得到的只是你在new File()時設定的路徑  
         */
        //比如當前的路徑為 D:\開發工程\GitHub\5_java_example\uritest\application : 
        try{ 
            File directory1 = new File("abc"); 
            System.out.println(directory1.getCanonicalPath());//輸出:D:\開發工程\GitHub\5_java_example\uritest\application\abc
            System.out.println(directory1.getAbsolutePath());//輸出:D:\開發工程\GitHub\5_java_example\uritest\application\abc 
            System.out.println(directory1.getPath());//輸出:abc 
        }catch(Exception e){}
        
        try{ 
            File directory2 = new File("."); 
            System.out.println(directory2.getCanonicalPath());//輸出:D:\開發工程\GitHub\5_java_example\uritest\application 
            System.out.println(directory2.getAbsolutePath());//輸出:D:\開發工程\GitHub\5_java_example\uritest\application\. 
            System.out.println(directory2.getPath());//輸出:. 
        }catch(Exception e){} 
        
        try{ 
            File directory3 = new File(".."); 
            System.out.println(directory3.getCanonicalPath());//輸出:D:\開發工程\GitHub\5_java_example\uritest 
            System.out.println(directory3.getAbsolutePath());//輸出:D:\開發工程\GitHub\5_java_example\uritest\application\.. 
            System.out.println(directory3.getPath());//輸出:.. 
        }catch(Exception e){} 

注意:以上輸出為eclipse的application的輸出。

測試JAR(Application):

正常,輸出如下:

測試WAR(Web):

正常,輸出如下:

總結:

①對於jar包來說,正常輸出所在目錄的路徑。(換句話說,就是這個程序在哪運行,目錄就定位在哪,但是不是精確到哪個類中的那種。)

②針對war包部署后,得到的是tomcat所在的根目錄。沒有精確到最根本的webapps目錄。

③File對象獲取的路徑只精確到工作目錄,而非class目錄,所以在對於一些配置文件放置在class中,File對象獲取時會比較麻煩,而且測試eclipse獲取的路徑和打包出jar時獲取的路徑是不一樣的。因此在寫法上需要來回切換。

④打包jar時,最終獲取的是jar文件所在的路徑,而這個路徑是絕對的,所以沒辦法獲取具體文件。而war包就是web容器的目錄,所以再加工一下,也可以看成是相對目錄,這個較容易處理。

 

3、在類中取得路徑:

參考:http://www.cnblogs.com/yejg1212/p/3270152.html

提示:如果不想要file:可以使用getPath()方法獲取,但是這樣前面還是會有/出現,最終只能是使用截取的方式去除。

 1      //類的絕對路徑,指的是編譯后字節碼class文件放置的位置根目錄
 2         System.out.println(ApplicationTest.class.getResource(""));//當前類(class)所在的包目錄,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/applicationtest/
 3         System.out.println(Class.class.getResource(""));//當前類(class)所在的包目錄,得到的會是null,因為沒有這個具體的類,輸出:null
 4         System.out.println(ApplicationTest.class.getResource("/"));//class path根目錄,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/
 5         System.out.println(Class.class.getResource("/"));//class path根目錄,與上面效果一致,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/
 6         System.out.println(ApplicationTest.class.getResource("/Test.xml"));//輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/Test.xml
 7         System.out.println(ApplicationTest.class.getResource("/applicationtest/Test2.xml"));//輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/applicationtest/Test2.xml
 8         System.out.println(Class.class.getResource("/applicationtest/Test2.xml"));//效果和上面一致,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/applicationtest/Test2.xml
 9         System.out.println(ApplicationTest.class.getResource("applicationtest/Test2.xml"));//沒有開頭的斜杠,無法確定起始的class path根目錄,輸出:null
10         System.out.println(Class.class.getResource("applicationtest/Test2.xml"));//效果和上面一致,輸出:null
11         //這里取資源文件有個技巧,在src文件夾下的資源文件,編譯后都會按照原有的路徑全部拷貝到class文件夾放置的位置下,因此會出現如上的取法
12         //當然,可以通過判斷獲取的對象是否為null來確定文件是否存在
13         //以下這種寫法會自動查找當前文件,但是只能查找當前類所在的包下的文件,如果有子包存在時,要帶上子包的路徑,同時開頭不需要斜杠。
14         System.out.println(ApplicationTest.class.getResource("Test.xml"));//不在當前類所在的包下,輸出:null
15         System.out.println(ApplicationTest.class.getResource("Test3.xml"));//不在當前類所在的包下,輸出:null
16         System.out.println(ApplicationTest.class.getResource("Test2.xml"));//不在當前類所在的包下,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/applicationtest/Test2.xml
17         System.out.println(Class.class.getResource("Test2.xml"));//返回null,說明還是沒有這個具體的類,所以找不到在哪里開始查找文件,輸出:null
18         //總結:綜上測試,具體的類獲取資源文件可以免去很多麻煩,建議使用具體的類進行獲取;還有中文路徑會經過轉碼。

注意:以上輸出為eclipse的application的輸出。

測試JAR(Application):

正常,輸出如下:

可以發現,這個輸出和eclipse中的輸出不一樣,其中獲取class path根目錄和類所在的包目錄已經無法獲取。而且值的路徑變了。

測試WAR(Web):

正常,輸出如下:

同樣可以發現路徑都是url編碼后的,中文也是如此。

總結:

①使用此方法,在jar和war中都能正常找到class的路徑。

②推薦使用具體的類取查找資源。Class在這里就已經無效。

③資源文件的查找方式在jar和war包保持一致。

 

對比:Class.getClassLoader().getResource()

 1      //類的絕對路徑,指的是編譯后字節碼class文件放置的位置根目錄
 2         System.out.println(ApplicationTest.class.getClassLoader().getResource(""));//class path根目錄,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/
 3         //System.out.println(Class.class.getClassLoader().getResource(""));//報錯
 4         System.out.println(ApplicationTest.class.getClassLoader().getResource("/"));//輸出:null
 5         //System.out.println(Class.class.getClassLoader().getResource("/"));//報錯
 6         System.out.println(ApplicationTest.class.getClassLoader().getResource("/Test.xml"));//輸出:null
 7         System.out.println(ApplicationTest.class.getClassLoader().getResource("/applicationtest/Test2.xml"));//輸出:null
 8         //System.out.println(Class.class.getClassLoader().getResource("/applicationtest/Test2.xml"));//報錯
 9         System.out.println(ApplicationTest.class.getClassLoader().getResource("applicationtest/Test2.xml"));//沒有開頭的斜杠,輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/applicationtest/Test2.xml
10         //System.out.println(Class.class.getClassLoader().getResource("applicationtest/Test2.xml"));//報錯
11         //這里取資源文件有個技巧,在src文件夾下的資源文件,編譯后都會按照原有的路徑全部拷貝到class文件夾放置的位置下,因此會出現如上的取法
12         //當然,可以通過判斷獲取的對象是否為null來確定文件是否存在
13         //以下這種寫法會自動查找當前文件,但是只能查找class根目錄下的文件,所在包下的文件無法找到
14         System.out.println(ApplicationTest.class.getClassLoader().getResource("Test.xml"));//輸出:file:/D:/%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b/GitHub/5_java_example/uritest/application/bin/Test.xml
15         System.out.println(ApplicationTest.class.getClassLoader().getResource("Test3.xml"));//輸出:null
16         System.out.println(ApplicationTest.class.getClassLoader().getResource("Test2.xml"));//輸出:null
17         //System.out.println(Class.class.getClassLoader().getResource("Test2.xml"));//報錯
18         //總結:綜上測試,具體的類獲取資源文件可以免去很多麻煩,建議使用具體的類進行獲取;還有中文路徑會經過轉碼。

 注意:以上結果為eclipse的application的輸出。

可以發現,Class.class的全部報錯了,而且ApplicationTest.class.getResource("/") == ApplicationTest.class.getClassLoader().getResource(""),也就是相反

測試JAR(Application):

正常,輸出如下:

結果和上面eclipse輸出的基本一致。

測試WAR(Web):

正常,輸出如下:

可以看出這個和jar的方式有很大區別,不管開頭有沒有斜杠都能正常輸出,而且都能找到這個文件Test2.xml。

總結:

①class.getClassLoader()這個方式在jar和war上其實有比較大的區別,如果為了統一的結果,建議不要使用這個方法。

②Class.class.getClassLoader可以用這個方法代替Thread.currentThread().getContextClassLoader(),效果一致。

③也可以用這個方法代替,和上面的效果一致:ClassLoader.getSystemClassLoader()。

 

4、File函數與類取路徑結合輸出:

     try{ 
            File directory1 = new File(ApplicationTest.class.getResource("/Test.xml").getPath()); 
            System.out.println(directory1.getCanonicalPath());//輸出:D:\%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b\GitHub\5_java_example\uritest\application\bin\Test.xml
            System.out.println(directory1.getAbsolutePath());//輸出: D:\%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b\GitHub\5_java_example\uritest\application\bin\Test.xml
            System.out.println(directory1.getPath());//輸出:D:\%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b\GitHub\5_java_example\uritest\application\bin\Test.xml
        }catch(Exception e){}

 

注意:以上輸出為eclipse的application的輸出。

可以看出完美解決了上面方法出現file開頭的問題。

測試JAR(Application):

正常,輸出如下:

可以發現,完全為空,所以這個方法在jar中是不靠譜。

測試WAR(Web):

正常,輸出如下:

總結:

①唯一的好處是去除了file開頭。

 

5、(Web)在JSP中獲取路徑:

<%=request.getSession().getServletContext().getRealPath("") %><br/><!-- //得到工程目錄, 參數可具體到包名。輸出:D:\開發工程\workspace_web\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\webtest;對於獲取資源文件的方法還可以這樣用:request.getSession().getServletContext().getResource("WEB-INF/web.xml") -->
<%=request.getRequestURL() %><br/><!-- //得到IE地址欄地址。輸出:http://localhost:8080/webtest/index.jsp -->
<%=request.getRequestURI() %><br/><!-- //得到相對地址,輸出:/webtest/index.jsp -->
<%=request.getServletPath() %><br/><!-- //根目錄所對應的絕對路徑,輸出:/index.jsp -->        
<%=request.getContextPath() %><br/><!-- //得到工程名,輸出://webtest --> 

可以發現,和servlet沒什么區別。

<%=application.getRealPath("index.jsp") %><br/><!-- //得到頁面所在服務器的全路徑,輸出://D:\開發工程\workspace_web\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\webtest\index.jsp --> 

對於application的用法還有很多,比如獲取文件夾的組合路徑(輸入upload)、根目錄(輸入/)即可。

 

6、(Web)在Servlet中獲取路徑:

     System.out.println(request.getSession().getServletContext().getRealPath(""));//得到工程目錄, 參數可具體到包名。輸出:D:\開發工程\workspace_web\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\webtest;對於獲取資源文件的方法還可以這樣用:request.getSession().getServletContext().getResource("WEB-INF/web.xml");比如getRealPath("/")得到的目錄后面自動帶上\或者/;
        System.out.println(request.getRequestURL());//得到IE地址欄地址。輸出:http://localhost:8080/webtest/UriTest
        System.out.println(request.getRequestURI());//得到相對地址,輸出:/webtest/UriTest
        System.out.println(request.getServletPath());//根目錄所對應的絕對路徑,輸出:/UriTest
        System.out.println(request.getContextPath());//得到工程名,輸出://webtest 

測試WAR(Web):

 

 

測試工程:https://github.com/easonjim/5_java_example/tree/master/uritest


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM