91无码视频一区|蜜臀福利在线观看|日韩一极黄色视频|色欲人妻少妇Av一区二区|婷婷香蕉视频欧美三级片黄色|一级A片刺激高潮|国产精品污污久久|日韩黄色精品日韩久久综合网|中国一级片电影在线|超碰乱码久久久免费

在java中獲取資源

2023-05-23


我們通常要做的一件事就是在開發(fā)java程序時獲取資源。那資源是什么?說到底,在電腦里就是一堆數(shù)據(jù)。只是這些數(shù)據(jù)對我們的java程序有多種表現(xiàn)形式,通常有File,URL,InputStream等。而且僅僅是文檔這個項目就有很多種:環(huán)境變量,java類文檔,jps文檔,照片,照片,css、js文檔等等。面對眾多的資源,當我們設計一個讀取資源的界面時,我們需要為不同形式的資源提供方法,這導致我們的界面仍然與實際的資源方法聯(lián)系在一起,并且沒有完全抽象。另外,資源在java系統(tǒng)中的存儲位置也各不相同。有的存儲在classpath中,有的存儲在文件系統(tǒng)中,有的存儲在web應用中。而且java程序在不同位置的資源中獲取這些資源的方法也不同。


A、在classpath中獲取資源:






URL url = this.getClass().getResource("resource_name");

    URL url = this.getClass().getClassLoader().getResource("resource_name");

    URL url = Thread.currentThread().getContextClassLoader().getResource("resource_name");





那為什么在jdk中又帶來了三種獲取classpath下資源的方法呢?這些都有一些來源。


在第一行代碼中,使用Class類的例子來獲取,第二行代碼是通過載入當前類的classloader來獲取的??纯磈dk中的源代碼,你會發(fā)現(xiàn)class類的例子最終被委托載入他的classloader來獲取資源。










public java.net.URL getResource(String name) {

    name = resolveName(name);

    ClassLoader cl = GetClassLoader0();

    if (cl==null) {

    // A system class.

    return ClassLoader.getSystemResource(name);

    }

    return cl.getResource(name);

    }









根據(jù)上述代碼可以看出,對于資源的載入,沒有像類載入所用的雙親委托機制。但當當前類的classloader不是null時,首先將資源從當前類的classloader中載入。而且只有當當前類的classloader是null時,system才是 在classloader中載入資源。因此,我們可以方便地定制配置類來覆蓋一些默認配置。當然,如果在j2se應用中沒有特別定制classloader,我們自己寫的類都是system。 載入classloader。到底用class獲取資源和使用classloader獲取資源的區(qū)別是什么?差別就在 resolveName(name)這是一種方法。這兩種形式對資源名稱的表達方式不同。以下是一個簡單的包結構,/表示類路徑的根。


/


|-com.cn.test


|-Test.class


|-test2.txt


|-test1.txt


代碼Java


// 獲得與當前類在同一包下的資源






URL url1 = this.getClass().getResource(test2.txt");





// 獲取com.cn.test包下的資源需要加//






URL url2 = this.getClass().getResource("/com/cn/test/test2.txt");





// 獲取類路徑根下的資源






URL url3 = this.getClass().getClassLoader().getResource(test1.txt");





// 取包com.cn.test包下的資源






URL url4 = this.getClass().getResource("com/cn/test/test2.txt");





裝載類的過程很簡單:找出類所在的位置,并將發(fā)現(xiàn)的Java類字節(jié)碼放入內(nèi)存中,生成相應的Class目標。Java的類裝載器是專門用來實現(xiàn)這一過程的,JVM不僅僅是一種類裝載器,事實上,如果你愿意的話,你可以讓JVM擁有無數(shù)的類裝載器,當然這除了檢測JVM之外,我還不明白其它的用途。你應該已經(jīng)發(fā)現(xiàn)了這樣一個問題。類裝載器本身也是一個類,也需要裝載到內(nèi)存中。誰來裝載這些類裝載器?總有根吧?是的,確實有這樣一個根,那就是Bootstrapp,神龍見頭不見尾。 ClassLoader. 為什么說它的龍看不到尾巴,因為你根本抓不住Java代碼里的一點尾巴,雖然你可以一直感受到它的存在,但是它本身就是C,因為java運行環(huán)境所需的所有類庫都是裝載的。 編寫程序,可獨立運行,可以算是JVM的運行起點,優(yōu)秀吧。當Bootstrap完成其任務后,它將生成一個AppClassLoader(實際上,在此之前,該系統(tǒng)還將使用擴展裝載器ExtClassLoader,它用于裝載Java運行環(huán)境擴展包中的類),這種裝載器是經(jīng)常使用的,可以調用ClassLoader。.getSystemClassLoader() 來獲取,假設我們沒有使用類裝載器在系統(tǒng)中的相關操作設置或定制新的類裝載器,那么我們編寫的所有java類都將由其裝載,這是值得尊重的。AppClassLoader搜索類的區(qū)域就是眾所周知的Classpath,也是初學者必須跨越的門檻,是否有一種閃光的感覺,我們根據(jù)它的搜索范圍來命名類路徑類裝載器?;蛘咧凹僭O的情況,當Java中出現(xiàn)一個新的類時,AppClassLoader首先將其傳達給其父類裝載器,即Extion。 ClassLoader,問問它能不能裝載這樣的東西,如果可以的話,那么AppClassLoader就不會做這份工作了,同樣Extion。 在裝載ClassLoader時,還會先問它的父類裝載器。不難發(fā)現(xiàn),類裝載器其實是一個樹形的框架圖。每個類裝載器都有自己的父親。類裝載器在裝載類裝載時,總是先裝載自己的父類裝載器(對長輩多么尊重)。如果父類裝載器不能裝載這種裝載器,它會自己裝載。如果它不能裝載,那么對不起,它會喊:Exception,class not found。當NoClassDefFoundException因直接類路徑裝載器裝載類失敗而拋出的時候,就是NoClassDefFoundException。如采用自定義的類裝載器loadClass方法或ClassLoaderfindSystemClass方法裝載類,如果您不刻意改變,則拋出ClassNotFoundException。


假如一個類是通過bootstrapp 如果我們輸入,那么如果我們通過這個類別獲得classloader,一些jdk的實現(xiàn)將返回null,例如,我使用它。 new Object().getClass().getClassLoader(),將回到null,這樣,NullPointer異常就會出現(xiàn)在上面的代碼中。.所以為了保險起見,我們最好還是用自己寫的類來獲得classloader("this.getClass().getClassLoader()"),這樣就不會有問題了。


B、在文件系統(tǒng)中獲取資源


代碼Java


// 1、獲得File目標






File file = new File("test.txt");





// 2、字節(jié)流以獲得File對象。






InputStream in = new FileInputStream(file);





值得注意的是,F(xiàn)ile的構造函數(shù)File(String name) name參數(shù)可以是相對路徑和絕對路徑。與System相比,相對路徑是.getProperties("user.dir")的。


C、在web應用中獲取資源






servletContext.getResourceAsStream(resource_name);





resource_names是相對于webroot的路徑表示。例如獲取webbes.xml,resource_name表示為“//”WEB-INF/web.xml"


面臨上述各種資源的表現(xiàn)形式和存儲位置,java難道沒有提供統(tǒng)一的處理方法嗎?是的,java.net.URL。


就名字而言 URL(Uniform Resource Locator) 統(tǒng)一資源定位儀??雌饋矸浅:茫浅姶?。但是很多時候使用它并不能定位我們需要的資源。


第一,其jdk系統(tǒng)中的URL可以瀏覽的協(xié)議非常有限(完全可以擴展,但是很麻煩);http是常用的,file,ftp等等。在classpath和servletContext中,沒有提供獲取資源的方法。


另外,它沒有提供方法來判斷資源是否存在。每一次,只有當我們真正獲得資源時,拋出異常才會知道資源無法獲得。


第二,URL這一類的職責沒有明確劃分,既用來表示資源可以用來獲取資源。


相對路徑在jsp和class文檔中有所不同。根目錄是jsp中的WebRoot。 根目錄是WebRoot//class文檔。WEB-INF/classes 當然你也可以使用System.getProperty("user.dir")得到你所有的工程路徑。
1.在jsp中獲取路徑:
以項目名稱TEST為例
(1)獲得包括工程名稱在內(nèi)的當前頁面全路徑:






request.getRequestURI()





結果:/TEST/test.jsp
(2)獲得工程名稱:






request.getContextPath()





結果:/TEST
獲得當前頁面所在目錄下的全名:






request.getServletPath()



結果:如果頁面在jsp目錄下 /TEST/jsp/test.jsp
(4)獲取頁面所在服務器的全部路徑:





application.getRealPath("test.jsp")




結果:D:\resin\webapps\TEST\test.jsp
(5)獲取頁面所在服務器的正確路徑:






absPath=new java.io.File(application.getRealPath(request.getRequestURI())).getParent();





結果:D:\resin\webapps\TEST
在類別中獲得路徑:
(1)類的盡對路徑:






Class.class.getClass().getResource("/").getPath()





(2)獲得工程的路徑:






System.getProperty("user.dir")



結果:D:\TEST
獲取Servlet中的路徑:
(1)獲得工程目錄:






request.getSession().getServletContext().getRealPath(")//參數(shù)可以具體到包名。





結果:E:\Tomcat\webapps\TEST
(2)獲取IE地址欄地址:






request.getRequestURL()





結果:http://localhost:8080/TEST/test
(3)獲得相對地址:





request.getRequestURI()




結果:/TEST/test


本文僅代表作者觀點,版權歸原創(chuàng)者所有,如需轉載請在文中注明來源及作者名字。

免責聲明:本文系轉載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權或非授權發(fā)布,請及時與我們聯(lián)系進行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com