最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑

 更新時(shí)間:2022年12月29日 11:29:41   作者:赤耳小永  
這篇文章主要介紹了解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

使用this.getClass().getResource()獲取文件時(shí)遇到的坑

最近在工作中遇到需要讀取配置文件,然后第一想法就是將文件放到項(xiàng)目的resources目錄下,

然后使用:

String fileName = "config/zh.md"
String path = this.getClass().getResource("/").getPath()  + fileName;
System.out.println(path);// D:/example/exam01/target/classes/config/zh.md

在IDE工具中開(kāi)發(fā)及Debug時(shí)一切都正常,但是打成Jar包發(fā)布到線上時(shí)就會(huì)出現(xiàn)java.io.FileNotFoundException

java.io.FileNotFoundException: file:/usr/local/exam01-1.0-SNAPSHOT.jar!/BOOT-INF/classes!/config/zh.md (No such file or directory)

錯(cuò)誤信息也已經(jīng)很明顯了,就是因?yàn)槲募淮嬖?,但是在IDE中是可以正常運(yùn)行了,那為什么打成jar包放到服務(wù)器中就不行了呢?

仔細(xì)檢查報(bào)錯(cuò)路徑發(fā)現(xiàn)在磁盤確實(shí)不存在這樣一條路徑,因?yàn)槁窂綇?.../exam01-1.0-SNAPSHOT.jar/...開(kāi)始,后面的文件路徑都是打到Jar包中的,磁盤沒(méi)有后面 .../BOOT-INF/classes!/config/zh.md這樣的目錄;

在Jar包中的文件在磁盤是沒(méi)有實(shí)際路徑的,所以這時(shí)候通過(guò) this.getClass()..getResource() 無(wú)法獲取文件。

解決方式一

直接將需要的文件上傳到服務(wù)器指定的文件夾下,如果把文件路徑寫(xiě)死,就太low了,也不符合編碼規(guī)范。

而且存在各種隱患例如:不同的環(huán)境發(fā)布到不同的服務(wù)器上,開(kāi)發(fā)一個(gè)服務(wù)器,測(cè)試一個(gè)服務(wù)器,生產(chǎn)一個(gè)服務(wù)器,每個(gè)服務(wù)器中都要上傳一份;如果誤刪或者遷移項(xiàng)目忘記遷移這個(gè)文件就麻煩了;

解決方式二

可以通過(guò) this.getClass()..getResourceAsStream("/config/zh.md") 能夠正常獲取到文件流。

xxx.class.getResource("")xxx.class.getClassLoader().getResource("")

上面問(wèn)題已經(jīng)解決了,我們看下xxx.class.getResource("") 和 **xxx.class.getClassLoader().getResource("")**的區(qū)別;

1.其實(shí)

class.getResource("/") == class.getClassLoader().getResource("");

Class.getResource和ClassLoader.getResource本質(zhì)上是一樣的,都是使用ClassLoader.getResource加載資源的。

對(duì)于Class.getResource:

先獲取文件的路徑path,不以’/‘開(kāi)頭時(shí),默認(rèn)是從此類所在的包下取資源;path以’/'開(kāi)頭時(shí),則是從項(xiàng)目的ClassPath根下獲取資源。

對(duì)于ClassLoader.getResource:

同樣先獲取文件的路徑,path不以’/'開(kāi)頭時(shí),首先通過(guò)雙親委派機(jī)制,使用的逐級(jí)向上委托的形式加載的,最后發(fā)現(xiàn)雙親沒(méi)有加載到文件,最后通過(guò)當(dāng)前類加載classpath根下資源文件。

對(duì)于getResource("/"),’/'表示Boot ClassLoader中的加載范圍,因?yàn)檫@個(gè)類加載器是C++實(shí)現(xiàn)的,所以加載范圍為null。

2.以上兩種方法返回的都是 java.net.URL對(duì)象

如果需要得到相應(yīng)的String類型,可以用以下方法:

xxx.class.getResource("").getPath();

xxx.class.getResource("").getFile();

或者通過(guò)

InputStream input = getClass().getClassLoader().getResourceAsStream("config\\config.properties");

獲取IO流;

3.類加載器ClassLoader

我們都知道 Java 文件被運(yùn)行,第一步,需要通過(guò) javac 編譯器編譯為 class 文件;第二步,JVM 運(yùn)行 class 文件,實(shí)現(xiàn)跨平臺(tái)。

而 JVM 虛擬機(jī)第一步肯定是 加載 class 文件,所以,類加載器實(shí)現(xiàn)的就是(來(lái)自《深入理解Java虛擬機(jī)》):

通過(guò)一個(gè)類的全限定名來(lái)獲取描述此類的二進(jìn)制字節(jié)流

類加載器有幾個(gè)重要的特性:

  • 每個(gè)類加載器都有自己的預(yù)定義的搜索范圍,用來(lái)加載 class 文件;
  • 每個(gè)類和加載它的類加載器共同確定了這個(gè)類的唯一性,也就是說(shuō)如果一個(gè) class 文件被不同的類加載器加載到了 JVM 中, 那么這兩個(gè)類就是不同的類,雖然他們都來(lái)自同一份 class 文件;

3.1 雙親委派模型

  • 所有的類加載器都是有層級(jí)結(jié)構(gòu)的,每個(gè)類加載器都有一個(gè)父類類加載器(通過(guò)組合實(shí)現(xiàn),而不是繼承),除了啟動(dòng)類加載器(Bootstrap ClassLoader)
  • 當(dāng)一個(gè)類加載器接收到一個(gè)類加載請(qǐng)求時(shí),首先將這個(gè)請(qǐng)求委派給它的父加載器去加載,所以每個(gè)類加載請(qǐng)求最終都會(huì)傳遞到頂層的啟動(dòng)類加載器,如果父加載器無(wú)法加載時(shí),子類加載器才會(huì)去嘗試自己去加載;

通過(guò)雙親委派模型就實(shí)現(xiàn)了類加載器的三個(gè)特性:

  • 委派(delegation):子類加載器委派給父類加載器加載;
  • 可見(jiàn)性(visibility):子類加載器可訪問(wèn)父類加載器加載的類,父類不能訪問(wèn)子類加載器加載的類;
  • 唯一性(uniqueness):可保證每個(gè)類只被加載一次,比如 Object 類是被 Bootstrap ClassLoader 加載的,因?yàn)橛辛穗p親委派模型,所有的 Object 類加載請(qǐng)求都委派到了 Bootstrap ClassLoader,所以保證了只被加載一次。

3.2 Java 中的類加載器

從 JVM 虛擬機(jī)的角度來(lái)看,只存在兩種不同的類加載器:

  • 啟動(dòng)類加載器(Bootstrap ClassLoader),是虛擬機(jī)自身的一部分;
  • 所有其他的類加載器,獨(dú)立于虛擬機(jī)外部,都繼承自抽象類 java.lang.ClassLoader

而絕大多數(shù) Java 應(yīng)用都會(huì)用到如下 3 中系統(tǒng)提供的類加載器:

  • 啟動(dòng)類加載器(Bootstrap/Primordial/NULL ClassLoader):頂層的類加載器,沒(méi)有父類加載器。負(fù)責(zé)加載 /lib 目錄下的,或則被 -Xbootclasspath 參數(shù)所指定路徑中的,

并被 JVM 識(shí)別的(僅按文件名識(shí)別,如 rt.jar,名字不符合的類庫(kù)即使放在 lib 目錄也不會(huì)被加載)類庫(kù)加載到虛擬機(jī)內(nèi)存中。所有被 Bootstrap classloader 加載的類,

它的 Class.getClassLoader 方法返回的都是 null,所以也稱作 NULL ClassLoader。

  • 擴(kuò)展類加載器(Extension CLassLoader):由 sun.misc.Launcher$ExtClassLoader 實(shí)現(xiàn),負(fù)責(zé)加載 <JAVA_HOME>/lib/ext 目錄下,或被 java.ext.dirs 系統(tǒng)變量所指定的目錄下的所有類庫(kù);
  • 應(yīng)用程序類加載器(Application/System ClassLoader):由 sun.misc.Launcher$AppClassLoader 實(shí)現(xiàn)。它是 ClassLoader.getSystemClassLoader() 方法的默認(rèn)返回值,

所以也稱為系統(tǒng)類加載器(System ClassLoader)。它負(fù)責(zé)加載 classpath 下所指定的類庫(kù),如果應(yīng)用程序沒(méi)有自定義過(guò)自己的類加載器,一般情況下這個(gè)就是程序中默認(rèn)的類加載器。

如下,就是 Java 程序中的類加載器層級(jí)結(jié)構(gòu)圖:

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java多線程 原子操作類詳細(xì)

    Java多線程 原子操作類詳細(xì)

    這篇文章主要介紹了Java多線程中的原子操作類,原子的本意是不能被分割的粒子,而對(duì)于一個(gè)操作來(lái)說(shuō),如果它是不可被中斷的一個(gè)或者一組操作,那么他就是原子操作。顯然,原子操作是安全的,因?yàn)樗粫?huì)被打斷,需要的朋友可以參考下
    2021-10-10
  • Java實(shí)現(xiàn)簡(jiǎn)單郵件發(fā)送

    Java實(shí)現(xiàn)簡(jiǎn)單郵件發(fā)送

    這篇文章主要介紹了Java實(shí)現(xiàn)簡(jiǎn)單郵件發(fā)送的相關(guān)資料,實(shí)例講解了java郵件發(fā)送實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Java NIO異步文件通道原理及用法解析

    Java NIO異步文件通道原理及用法解析

    這篇文章主要介紹了Java NIO異步文件通道原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • java金錢處理方法實(shí)例詳解

    java金錢處理方法實(shí)例詳解

    這篇文章主要介紹了java金錢處理方法實(shí)例詳解的相關(guān)資料,這里提供實(shí)現(xiàn)方法分轉(zhuǎn)化成元的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2017-08-08
  • xml 的特殊字符的處理方法

    xml 的特殊字符的處理方法

    在xml中,有一些符號(hào)作為XML 的標(biāo)記符號(hào),一些特定情況下,屬性值必須帶有這些特殊符號(hào)?!∠旅嬷饕侵v解一些常用的特殊符號(hào)的處理
    2016-07-07
  • Java 動(dòng)態(tài)代理你真的懂了嗎(動(dòng)態(tài)和代理)

    Java 動(dòng)態(tài)代理你真的懂了嗎(動(dòng)態(tài)和代理)

    動(dòng)態(tài)代理分兩部分,動(dòng)態(tài)和代理,今天通過(guò)本文給大家普及代碼模式及動(dòng)態(tài)代理的概念及示例代碼,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • mybatis generator 配置 反向生成Entity簡(jiǎn)單增刪改查(推薦)

    mybatis generator 配置 反向生成Entity簡(jiǎn)單增刪改查(推薦)

    這篇文章主要介紹了mybatis generator 配置 反向生成Entity簡(jiǎn)單增刪改查(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-12-12
  • BootStrap Jstree 樹(shù)形菜單的增刪改查的實(shí)現(xiàn)源碼

    BootStrap Jstree 樹(shù)形菜單的增刪改查的實(shí)現(xiàn)源碼

    這篇文章主要介紹了BootStrap Jstree 樹(shù)形菜單的增刪改查的實(shí)現(xiàn)源碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • mybatis通過(guò)if語(yǔ)句實(shí)現(xiàn)增刪改查操作

    mybatis通過(guò)if語(yǔ)句實(shí)現(xiàn)增刪改查操作

    這篇文章主要介紹了mybatis通過(guò)if語(yǔ)句實(shí)現(xiàn)增刪改查操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • Java使用設(shè)計(jì)模式中的代理模式構(gòu)建項(xiàng)目的實(shí)例展示

    Java使用設(shè)計(jì)模式中的代理模式構(gòu)建項(xiàng)目的實(shí)例展示

    這篇文章主要介紹了Java使用設(shè)計(jì)模式中的代理模式構(gòu)建項(xiàng)目的實(shí)例展示,代理模式中的代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用,需要的朋友可以參考下
    2016-05-05

最新評(píng)論

双辽市| 类乌齐县| 伊宁县| 大宁县| 镇巴县| 尚义县| 石城县| 台州市| 南昌市| 安仁县| 盐源县| 伊金霍洛旗| 潞城市| 托克托县| 武冈市| 安平县| 博乐市| 沙雅县| 黔东| 土默特右旗| 凤凰县| 漠河县| 景德镇市| 泊头市| 阿巴嘎旗| 迁西县| 五原县| 阳曲县| 洪洞县| 湘潭市| 博湖县| 榆社县| 成都市| 潜江市| 渭南市| 伊金霍洛旗| 吉水县| 轮台县| 扎兰屯市| 增城市| 苏尼特左旗|