<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在工作中遇到需要讀取組態檔,然後第一想法就是將檔案放到專案的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("")**的區別;
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。
如果需要得到相應的String型別,可以用以下方法:
xxx.class.getResource("").getPath(); xxx.class.getResource("").getFile();
或者通過
InputStream input = getClass().getClassLoader().getResourceAsStream("config\config.properties");
獲取IO流;
我們都知道 Java 檔案被執行,第一步,需要通過 javac
編譯器編譯為 class 檔案;第二步,JVM 執行 class 檔案,實現跨平臺。
而 JVM 虛擬機器器第一步肯定是 載入 class 檔案,所以,類載入器實現的就是(來自《深入理解Java虛擬機器器》):
通過一個類的全限定名來獲取描述此類的二進位制位元組流
類載入器有幾個重要的特性:
3.1 雙親委派模型
通過雙親委派模型就實現了類載入器的三個特性:
Object
類是被 Bootstrap ClassLoader 載入的,因為有了雙親委派模型,所有的 Object 類載入請求都委派到了 Bootstrap ClassLoader,所以保證了只被載入一次。3.2 Java 中的類載入器
從 JVM 虛擬機器器的角度來看,只存在兩種不同的類載入器:
java.lang.ClassLoader
而絕大多數 Java 應用都會用到如下 3 中系統提供的類載入器:
並被 JVM 識別的(僅按檔名識別,如 rt.jar,名字不符合的類庫即使放在 lib 目錄也不會被載入)類庫載入到虛擬機器器記憶體中。所有被 Bootstrap classloader 載入的類,
它的 Class.getClassLoader 方法返回的都是 null,所以也稱作 NULL ClassLoader。
sun.misc.Launcher$ExtClassLoader
實現,負責載入 <JAVA_HOME>/lib/ext
目錄下,或被 java.ext.dirs
系統變數所指定的目錄下的所有類庫;sun.misc.Launcher$AppClassLoader
實現。它是 ClassLoader.getSystemClassLoader() 方法的預設返回值,所以也稱為系統類載入器(System ClassLoader)。它負責載入 classpath 下所指定的類庫,如果應用程式沒有自定義過自己的類載入器,一般情況下這個就是程式中預設的類載入器。
如下,就是 Java 程式中的類載入器層級結構圖:
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45