亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2022-12-29 16:23:27 來源:億速云 閱讀:195 作者:iii 欄目:開發技術

這篇文章主要介紹“使用this.getClass().getResource()獲取文件時遇到的坑怎么解決”,在日常操作中,相信很多人在使用this.getClass().getResource()獲取文件時遇到的坑怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”使用this.getClass().getResource()獲取文件時遇到的坑怎么解決”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

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

    最近在工作中遇到需要讀取配置文件,然后第一想法就是將文件放到項目的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工具中開發及Debug時一切都正常,但是打成Jar包發布到線上時就會出現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)

    錯誤信息也已經很明顯了,就是因為文件不存在,但是在IDE中是可以正常運行了,那為什么打成jar包放到服務器中就不行了呢?

    仔細檢查報錯路徑發現在磁盤確實不存在這樣一條路徑,因為路徑從 .../exam01-1.0-SNAPSHOT.jar/...開始,后面的文件路徑都是打到Jar包中的,磁盤沒有后面 .../BOOT-INF/classes!/config/zh.md這樣的目錄;

    在Jar包中的文件在磁盤是沒有實際路徑的,所以這時候通過 this.getClass()..getResource() 無法獲取文件。

    解決方式一

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

    而且存在各種隱患例如:不同的環境發布到不同的服務器上,開發一個服務器,測試一個服務器,生產一個服務器,每個服務器中都要上傳一份;如果誤刪或者遷移項目忘記遷移這個文件就麻煩了;

    解決方式二

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

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

    上面問題已經解決了,我們看下xxx.class.getResource("") 和 **xxx.class.getClassLoader().getResource("")**的區別;

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

    1.其實

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

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

    對于Class.getResource:

    先獲取文件的路徑path,不以’/‘開頭時,默認是從此類所在的包下取資源;path以’/'開頭時,則是從項目的ClassPath根下獲取資源。

    對于ClassLoader.getResource:

    同樣先獲取文件的路徑,path不以’/'開頭時,首先通過雙親委派機制,使用的逐級向上委托的形式加載的,最后發現雙親沒有加載到文件,最后通過當前類加載classpath根下資源文件。

    對于getResource("/"),’/'表示Boot ClassLoader中的加載范圍,因為這個類加載器是C++實現的,所以加載范圍為null。

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

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

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

    或者通過

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

    獲取IO流;

    3.類加載器ClassLoader

    我們都知道 Java 文件被運行,第一步,需要通過 javac 編譯器編譯為 class 文件;第二步,JVM 運行 class 文件,實現跨平臺。

    而 JVM 虛擬機第一步肯定是 加載 class 文件,所以,類加載器實現的就是:

    通過一個類的全限定名來獲取描述此類的二進制字節流

    類加載器有幾個重要的特性:

    • 每個類加載器都有自己的預定義的搜索范圍,用來加載 class 文件;

    • 每個類和加載它的類加載器共同確定了這個類的唯一性,也就是說如果一個 class 文件被不同的類加載器加載到了 JVM 中, 那么這兩個類就是不同的類,雖然他們都來自同一份 class 文件;

    3.1 雙親委派模型

    • 所有的類加載器都是有層級結構的,每個類加載器都有一個父類類加載器(通過組合實現,而不是繼承),除了啟動類加載器(Bootstrap ClassLoader)

    • 當一個類加載器接收到一個類加載請求時,首先將這個請求委派給它的父加載器去加載,所以每個類加載請求最終都會傳遞到頂層的啟動類加載器,如果父加載器無法加載時,子類加載器才會去嘗試自己去加載;

    通過雙親委派模型就實現了類加載器的三個特性:

    • 委派(delegation):子類加載器委派給父類加載器加載;

    • 可見性(visibility):子類加載器可訪問父類加載器加載的類,父類不能訪問子類加載器加載的類;

    • 唯一性(uniqueness):可保證每個類只被加載一次,比如 Object 類是被 Bootstrap ClassLoader 加載的,因為有了雙親委派模型,所有的 Object 類加載請求都委派到了 Bootstrap ClassLoader,所以保證了只被加載一次。

    3.2 Java 中的類加載器

    從 JVM 虛擬機的角度來看,只存在兩種不同的類加載器:

    • 啟動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分;

    • 所有其他的類加載器,獨立于虛擬機外部,都繼承自抽象類 java.lang.ClassLoader

    而絕大多數 Java 應用都會用到如下 3 中系統提供的類加載器:

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

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

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

    • 擴展類加載器(Extension CLassLoader):由 sun.misc.Launcher$ExtClassLoader 實現,負責加載 <JAVA_HOME>/lib/ext 目錄下,或被 java.ext.dirs 系統變量所指定的目錄下的所有類庫;

    • 應用程序類加載器(Application/System ClassLoader):由 sun.misc.Launcher$AppClassLoader 實現。它是 ClassLoader.getSystemClassLoader() 方法的默認返回值,

    所以也稱為系統類加載器(System ClassLoader)。它負責加載 classpath 下所指定的類庫,如果應用程序沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。

    如下,就是 Java 程序中的類加載器層級結構圖:

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

    到此,關于“使用this.getClass().getResource()獲取文件時遇到的坑怎么解決”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    临夏县| 连州市| 疏附县| 岳普湖县| 巴楚县| 义马市| 建昌县| 库尔勒市| 屏山县| 涞水县| 曲阜市| 缙云县| 眉山市| 墨玉县| 饶河县| 内黄县| 九龙县| 清涧县| 边坝县| 阜康市| 蓝田县| 沐川县| 绥宁县| 临清市| 开鲁县| 南和县| 海口市| 福建省| 阳曲县| 克拉玛依市| 博爱县| 珲春市| 长白| 咸丰县| 常州市| 科尔| 大悟县| 托克逊县| 嘉鱼县| 祁连县| 永城市|