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

解析Java和IDEA中的文件打包問(wèn)題

 更新時(shí)間:2021年07月29日 09:10:26   作者:返回主頁(yè)lilpig  
這篇文章主要介紹了Java和IDEA中的文件打包問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

問(wèn)題:想在IDEA中引用相對(duì)路徑,但是找不到文件。

項(xiàng)目目錄結(jié)構(gòu)

當(dāng)前項(xiàng)目的路徑為:D:\source\java\test\

項(xiàng)目結(jié)構(gòu)如下

當(dāng)前路徑

面對(duì)無(wú)法使用相對(duì)路徑找到資源文件的問(wèn)題,首先想到的解決辦法是先瞄一眼IDEA在執(zhí)行時(shí)給Java環(huán)境設(shè)定的當(dāng)前路徑在哪,也就是說(shuō)看看我們?cè)谑褂孟鄬?duì)路徑時(shí)到底是相對(duì)于哪里的。

應(yīng)該咋寫(xiě)呢?下面是Java API中的一些描述。

默認(rèn)情況下, java.io包中的類始終會(huì)根據(jù)當(dāng)前用戶目錄解析相對(duì)路徑名。 該目錄由系統(tǒng)屬性u(píng)ser.dir ,通常是調(diào)用Java虛擬機(jī)的目錄。

根據(jù)上面的信息,可以想到兩個(gè)辦法來(lái)獲得當(dāng)前路徑,第一種辦法是向Java中傳遞空字符串,這是一個(gè)比較hack的方法,按照相對(duì)路徑來(lái)解析的話,自然會(huì)被解析成當(dāng)前目錄。

File f1 = new File(""); // 空字符串,相當(dāng)于當(dāng)前路徑
System.out.println(f1.getAbsolutePath());

第二種辦法,直接獲取系統(tǒng)屬性中的user.dir

System.out.println(System.getProperty("user.dir"));

兩種辦法得到的結(jié)果一致:

也就是說(shuō),當(dāng)前目錄指向項(xiàng)目的根目錄,如果你想要獲取src中的一個(gè)文件的話,需要使用src/文件名,而如果該文件在某個(gè)包下的話,則需要使用src/完整包路徑/文件名

現(xiàn)在我在src下創(chuàng)建一個(gè)文件text1.txt,寫(xiě)入內(nèi)容HELLO , WORLD

File f2 = new File("src/text1.txt");
LineNumberReader reader2 = new LineNumberReader(new FileReader(f2));
System.out.println(reader2.readLine());

結(jié)果

這樣寫(xiě)好嗎?

我們的Java代碼最終會(huì)被打包上傳到目標(biāo)平臺(tái),如某個(gè)服務(wù)器上,打包的代碼應(yīng)該只包含編譯后的文件目錄,在IDEA中就是那個(gè)out目錄,其它的文件都不會(huì)出現(xiàn)在目標(biāo)平臺(tái)上,到那個(gè)時(shí)候,你不再擁有當(dāng)前項(xiàng)目編寫(xiě)時(shí)的目錄結(jié)構(gòu),你的程序運(yùn)行時(shí)所在的當(dāng)前路徑也不再是現(xiàn)在這個(gè)。

簡(jiǎn)單來(lái)說(shuō),我們寫(xiě)出了依賴環(huán)境的代碼,這個(gè)代碼不保證程序運(yùn)行在生產(chǎn)環(huán)境下的時(shí)候還可以正常執(zhí)行,而且通常是無(wú)法正常執(zhí)行。

唯一的辦法,就是我們?cè)贗DEA編譯時(shí),告訴它有些文件,請(qǐng)你幫我打包到out目錄中,然后我再想辦法去out目錄中找,這下就不會(huì)出問(wèn)題了。

JavaAPI中有這樣一個(gè)方法,它被明確說(shuō)明是用來(lái)干這個(gè)事的就是ClassLoader中的getResource,下面是API中的說(shuō)明

尋找給定名字的資源文件。一個(gè)資源文件可以是一些能夠被class代碼以一種獨(dú)立于代碼位置的方式進(jìn)行訪問(wèn)的數(shù)據(jù)(圖像、聲音、文字等)

我們先看看使用這個(gè)方法是相對(duì)于哪個(gè)路徑,采用的辦法和new File("")大同小異。

String path = Main.class.getClassLoader().getResource("").getPath();
System.out.println(path);

結(jié)果如下

它已經(jīng)找到了我們打包后的二進(jìn)制代碼所在的位置,這下就可以相對(duì)于二進(jìn)制代碼的位置讀寫(xiě)文件了,不再依賴當(dāng)前環(huán)境。

注意,ClassLoader.getResourceAsStream和Class.getResourceAsStream有些細(xì)微的區(qū)別,見(jiàn)JAVA 筆記 ClassLoader.getResourceAsStream() 與 Class.getResourceAsStream()的區(qū)別

將文件打包到二進(jìn)制代碼位置

創(chuàng)建文件夾,mark directory as -> Resources Root。

o

在其中創(chuàng)建text2.txt,寫(xiě)入HELLO , RESOURCES

然后這樣去讀

LineNumberReader r3 = new LineNumberReader(
        new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("text2.txt"))
);
System.out.println(r3.readLine());

這里使用了ClassLoader.getResource的一個(gè)變體getResourceAsStream,它的作用就是返回的是一個(gè)流,而非URL。我們所做的就是獲取當(dāng)前類的ClassLoader,通過(guò)它獲取資源文件,轉(zhuǎn)換成LineNumberReader。

讀取成功,也就是說(shuō),在resources文件夾下的文件,IDEA會(huì)自動(dòng)幫我們打包到二進(jìn)制代碼的位置

其他

src中的文件

如果我們?nèi)タ?code>out文件夾下的文件結(jié)構(gòu),你就會(huì)發(fā)現(xiàn),除了resources/text2.txt,我們之前在src下創(chuàng)建的text1.txt也被打包到這個(gè)位置了。也就是說(shuō),我們可以通過(guò)同樣的方式去讀取src下的文件。

D:\source\java\test\out>wsl tree .
.
└── production
    └── test
        ├── io
        │   └── lilpig
        │       └── test
        │           └── Main.class
        ├── text1.txt
        └── text2.txt

5 directories, 3 files

LineNumberReader r4 = new LineNumberReader(
        new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("text1.txt"))
);
System.out.println(r4.readLine());

讀取成功

Thread.currentThread.getContextClassLoader

在多線程應(yīng)用中,有可能你編寫(xiě)的類的類加載器和實(shí)際加載resources文件夾的類加載器不是同一個(gè),這會(huì)導(dǎo)致你的代碼無(wú)法獲取到資源文件,使用Thread.currentThread.getContextClassLoader能規(guī)避這個(gè)問(wèn)題。具體的原理涉及到Java中的類加載機(jī)制的委托模型,這部分的內(nèi)容原理性太強(qiáng),我已經(jīng)忘得差不多了,就不露怯了。

我們編寫(xiě)的大部分后端應(yīng)用,都是多線程應(yīng)用,我們自己感知不到,那是因?yàn)槎嗑€程代碼被封裝在框架中,所以無(wú)論如何,使用Thread.currentThread.getContextClassLoader總比使用Main.class.getClassLoader更好。

并且,Thread.currentThread.getContextClassLoader更加具有一致性,你可以輕易的編寫(xiě)一個(gè)工具方法來(lái)簡(jiǎn)化代碼(無(wú)論如何Thread.currentThread返回的總是當(dāng)前調(diào)用者所在的線程)。而如果用之前的方法,每一個(gè)類的類名都不同,你在一個(gè)類中寫(xiě)的是Main.class.getClassLoader在另一個(gè)類中寫(xiě)的又是Other.class.getClassLoader,這不一致的代碼會(huì)讓我們難以編寫(xiě)一個(gè)通用的工具類。

框架

在框架中,資源文件夾都是默認(rèn)被創(chuàng)建好的,有的可能叫static,有的可能叫resources......而且,有可能編譯后的目錄不是out,而是target,甚至?xí)淮虬?code>war包等。

我們要做的不是管它打包后在哪,而是直接往框架給你指定好的資源文件夾里面放文件就行,剩下的交給框架。

并且在框架中,隨處可見(jiàn)Thread.currentThread.getClassLoader().getResource...這樣的代碼。

參考

Java SE 8 API

Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()區(qū)別

到此這篇關(guān)于Java和IDEA中的文件打包的文章就介紹到這了,更多相關(guān)Java和IDEA中的文件打包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)elasticsearch索引操作的代碼示例

    SpringBoot實(shí)現(xiàn)elasticsearch索引操作的代碼示例

    這篇文章主要給大家介紹了SpringBoot如何實(shí)現(xiàn)elasticsearch 索引操作,文中有詳細(xì)的代碼示例,感興趣的同學(xué)可以參考閱讀下
    2023-07-07
  • springboot中使用過(guò)濾器,jsoup過(guò)濾XSS腳本詳解

    springboot中使用過(guò)濾器,jsoup過(guò)濾XSS腳本詳解

    這篇文章主要介紹了springboot中使用過(guò)濾器,jsoup過(guò)濾XSS腳本詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • IDEA整合jeesite4.x及安裝教程

    IDEA整合jeesite4.x及安裝教程

    本文給大家介紹IDEA整合jeesite4.x及安裝教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Java源碼解析之詳解ReentrantLock

    Java源碼解析之詳解ReentrantLock

    今天給大家?guī)?lái)的是關(guān)于Java并發(fā)的相關(guān)知識(shí),文章圍繞著ReentrantLock源碼展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Java線程池復(fù)用線程的秘密你知道嗎

    Java線程池復(fù)用線程的秘密你知道嗎

    這篇文章主要為大家詳細(xì)介紹了Java線程池復(fù)用線程的秘密,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望您能夠多多關(guān)注

    2022-03-03
  • Java使用泛型實(shí)現(xiàn)棧結(jié)構(gòu)的示例代碼

    Java使用泛型實(shí)現(xiàn)棧結(jié)構(gòu)的示例代碼

    泛型是JAVA重要的特性,使用泛型編程,可以使代碼復(fù)用率提高。本文將利用泛型實(shí)現(xiàn)簡(jiǎn)單的棧結(jié)構(gòu),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • Java多線程ThreadAPI詳細(xì)介紹

    Java多線程ThreadAPI詳細(xì)介紹

    這篇文章主要介紹了Java多線程ThreadAPI詳細(xì)介紹,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 詳解Java分布式事務(wù)的 6 種解決方案

    詳解Java分布式事務(wù)的 6 種解決方案

    在分布式系統(tǒng)、微服務(wù)架構(gòu)大行其道的今天,服務(wù)間互相調(diào)用出現(xiàn)失敗已經(jīng)成為常態(tài),本文側(cè)重于其他幾項(xiàng),關(guān)于 2PC、3PC 傳統(tǒng)事務(wù),網(wǎng)上資料已經(jīng)非常多了,這里不多做重復(fù),本文通過(guò)示例給大家介紹Java分布式事務(wù)的 6 種解決方案,一起看看吧
    2021-06-06
  • 啟動(dòng)SpringBoot報(bào)錯(cuò)Input length = 1問(wèn)題及解決

    啟動(dòng)SpringBoot報(bào)錯(cuò)Input length = 1問(wèn)題及解決

    這篇文章主要介紹了啟動(dòng)SpringBoot報(bào)錯(cuò)Input length = 1問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 關(guān)于Springboot如何獲取IOC容器

    關(guān)于Springboot如何獲取IOC容器

    大家好,我是孤焰。最近我在制作日志審計(jì)功能時(shí)發(fā)現(xiàn)不知道怎樣獲取到Springboot項(xiàng)目中的IOC容器,經(jīng)過(guò)摸索,最終解決了這個(gè)問(wèn)題,現(xiàn)在把解決方式和大家分享一下
    2021-08-08

最新評(píng)論

珠海市| 句容市| 湘潭县| 邻水| 饶阳县| 宁陵县| 绥滨县| 河池市| 民权县| 宁津县| 长垣县| 平潭县| 绍兴市| 海原县| 阿拉善盟| 和田市| 公主岭市| 河南省| 台东市| 博爱县| 曲阜市| 桂林市| 黑水县| 太白县| 灵山县| 南宁市| 彭泽县| 朝阳市| 长泰县| 中西区| 洪雅县| 文山县| 台北市| 吴旗县| 蒲城县| 突泉县| 涿州市| 舞阳县| 共和县| 微博| 滦平县|