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

java實(shí)現(xiàn)讀取jar包中配置文件的幾種方式

 更新時(shí)間:2023年06月15日 11:33:43   作者:奔跑吧人生  
本文主要介紹了java實(shí)現(xiàn)讀取jar包中配置文件的幾種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

概述

在編程的某些情況下,我們需要讀取jar包中的文件,這種情況要區(qū)別于我們平時(shí)使用類加載器讀取配置文件,這個(gè)時(shí)候配置在jar包中,就能讀取到,但是配置文件也可以不在jar包中,只要放在Class-Path下就行了,所以這種情況下,我更愿意把它稱之為:讀取Class-Path下的配置文件。而我今天描述的比較明確,就是要讀取jar包中的文件。這種需求可能不多,但是我碰見了,并且發(fā)現(xiàn)了幾種,今天全部羅列分享一下。

目前有3種:

  • JarFile
  • URL
  • ClassLoader

定義接口

因?yàn)橛泻脦追N方式,那就直接定義個(gè)接口:

public interface JarReader {
   /**
     * 讀取jar包中的文件
     * @param jarPath   jar包路徑
     * @param file  jar包中的文件路徑
     * @return  文件內(nèi)容,轉(zhuǎn)換成字符串了,其它需求也可以轉(zhuǎn)換成輸入流。
     * @throws IOException
     */
    String readFromJar(String jarPath,String file) throws IOException;
}

jar包讀取器,jar包中的文件讀取出來。

通過JarFile讀取

JarFile是java自帶的一種讀取jar包的API,很多人應(yīng)該用過,我就直接貼代碼了。public class JarFileJarReader implements JarReader {
? ? @Override
? ? public String readFromJar(String jarPath,String file) throws IOException {
? ? ? ? JarFile jarFile=null;
? ? ? ? try {
? ? ? ? ? ? jarFile=new JarFile(jarPath);
? ? ? ? ? ? JarEntry jarEntry=jarFile.getJarEntry(file);
? ? ? ? ? ? InputStream input=jarFile.getInputStream(jarEntry);
? ? ? ? ? ? return IOUtils.toString(input,"UTF-8");
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? throw e;
? ? ? ? } finally {
? ? ? ? ? ? IOUtils.closeQuietly(jarFile);
? ? ? ? }
? ? }
}

代碼也比較簡(jiǎn)單,重點(diǎn)就是最后一定要把jarFile這個(gè)對(duì)象關(guān)閉一下,中間的輸入流都可以不用關(guān)閉。

不過我在寫這段代碼之前,從我的個(gè)人經(jīng)驗(yàn)上來說,JarFile好像更多是用來讀取清單文件(MANIFEST.MF)的,可能是見這種情況比較多,當(dāng)然它的用途肯定遠(yuǎn)不止如此。
因此我順便寫了一下讀取清單文件的代碼:

public void getManiFest(String jarPath) throws IOException {
? ? ? ? JarFile jarFile=null;
? ? ? ? try {
? ? ? ? ? ? jarFile=new JarFile(jarPath);
? ? ? ? ? ? Manifest manifest=jarFile.getManifest();
? ? ? ? ? ? if (manifest!=null){
? ? ? ? ? ? ? ? //獲取Class-Path
? ? ? ? ? ? ? ? String classPaths = (String) manifest.getMainAttributes().get(new Attributes.Name("Class-Path"));
? ? ? ? ? ? ? ? if (classPaths != null && !classPaths.isEmpty()) {
? ? ? ? ? ? ? ? ? ? String[] classPathArray = classPaths.split(" ");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //獲取JDK版本
? ? ? ? ? ? ? ? String jdkVersion = (String) manifest.getMainAttributes().get(new Attributes.Name("Build-Jdk"));
? ? ? ? ? ? ? ? //還可以獲取其它內(nèi)容,比如Main-Class等等
? ? ? ? ? ? }
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? throw e;
? ? ? ? } finally {
? ? ? ? ? ? IOUtils.closeQuietly(jarFile);
? ? ? ? }
? ? }

通過URL讀取

java自帶的URL是支持讀取jar中的文件的,協(xié)議是jar,表示方式的話是用"/!"把jar包和文件區(qū)分一下。代碼如下:

public class URLJarReader implements JarReader {
    @Override
    public String readFromJar(String jarPath, String file) throws IOException {
        JarURLConnection jarURLConnection=null;
        try {
            URL fileUrl=ParseUtil.fileToEncodedURL(new File(jarPath));
            URL jarUrl=new URL("jar", "", -1, fileUrl + "!/");
            URL moduleUrl = new URL(jarUrl, ParseUtil.encodePath(file, false));
            jarURLConnection = (JarURLConnection)moduleUrl.openConnection();
            return IOUtils.toString(jarURLConnection.getInputStream(),"UTF-8");
        } catch (IOException e) {
            throw e;
        } finally {
            if (jarURLConnection!=null){
                try {
                    jarURLConnection.getJarFile().close();
                } catch (IOException ignore) {
                }
            }
        }
    }
}

ParseUtil的幾個(gè)方法是我在看java源碼的時(shí)候看見的,用來處理一些不規(guī)則的文件路徑。

我剛開始用URL的時(shí)候,就出現(xiàn)了一個(gè)內(nèi)存泄漏的文件,讀取完了以后,jar包被占用,死活不能刪除,剛才開始把輸入流給關(guān)閉了,也沒有用。然后想到了類加載器里面有close方法,然后去看了一下,找到了上述代碼中的finally塊的代碼。這樣就可以把占用問題解決了,仔細(xì)看的話,會(huì)發(fā)現(xiàn),getJarFile.close(),因此本質(zhì)上還是關(guān)閉了JarFile,和上面是一樣的。

通過ClassLoader

這個(gè)也是借鑒了我們平時(shí)讀取配置文件的方式,借用一下ClassLoader來讀取。

public class ClassLoaderJarReader implements JarReader {
    @Override
    public String readFromJar(String jarPath, String file) throws IOException{
        URLClassLoader urlClassLoader=null;
        try {
            URL fileUrl=ParseUtil.fileToEncodedURL(new File(jarPath));
            urlClassLoader=new URLClassLoader(new URL[]{fileUrl},null);
            InputStream inputStream=urlClassLoader.getResourceAsStream(file);
            if (inputStream==null){
                throw new FileNotFoundException("not find file:"+file+" in jar:"+jarPath);
            }else{
                return IOUtils.toString(inputStream,"UTF-8");
            }
        } catch (IOException e) {
            throw e;
        } finally {
            IOUtils.closeQuietly(urlClassLoader);
        }
    }
}

代碼也是比較簡(jiǎn)單,最后把ClassLoader關(guān)閉一下就行了。

關(guān)于類加載器的讀取方式,我很早之前就看過了,它本質(zhì)上用的就是上面兩種方式結(jié)合起來讀取文件的。

總結(jié)

這幾種方式的話,其實(shí)沒有什么區(qū)別,從開發(fā)角度來說的話,比較推薦第三種,因?yàn)槭莏ava自帶的功能,也是比較完善,也簡(jiǎn)單,也不容易出錯(cuò),而且它內(nèi)部用的就是前面兩種。不過從資源消耗上面來說,我猜測(cè),前面兩種應(yīng)該占優(yōu),不過我也不糾結(jié)這個(gè),沒去研究。

有時(shí)候我們或許有另外一種需求,讀取jar中的jar中的文件,這個(gè)在一些場(chǎng)景下,會(huì)使用到。最起碼spring-boot確實(shí)是用到了,很早之前我看過它的實(shí)現(xiàn),它就是把URL重寫了一下,支持了一下多個(gè)"/!"表達(dá)式,就能夠支持這種情況了。

到此這篇關(guān)于java實(shí)現(xiàn)讀取jar包中配置文件的幾種方式的文章就介紹到這了,更多相關(guān)java 讀取jar包配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Aware源碼設(shè)計(jì)示例解析

    Spring Aware源碼設(shè)計(jì)示例解析

    這篇文章主要為大家介紹了Spring Aware源碼設(shè)計(jì)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • HttpMessageConverter報(bào)文信息轉(zhuǎn)換器的深入講解

    HttpMessageConverter報(bào)文信息轉(zhuǎn)換器的深入講解

    在Spring中內(nèi)置了大量的HttpMessageConverter,通過請(qǐng)求頭信息中的MIME類型,選擇相應(yīng)的HttpMessageConverter,這篇文章主要給大家介紹了關(guān)于HttpMessageConverter報(bào)文信息轉(zhuǎn)換器的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Java線上問題排查過程

    Java線上問題排查過程

    本文詳細(xì)介紹了如何通過命令行和可視化工具來診斷和解決CPU和內(nèi)存使用率過高的問題,包括找到高占用率的進(jìn)程和線程,分析堆內(nèi)存使用情況,以及在內(nèi)存溢出時(shí)自動(dòng)保存堆快照文件的方法
    2026-03-03
  • Maven坐標(biāo)和依賴的實(shí)現(xiàn)示例

    Maven坐標(biāo)和依賴的實(shí)現(xiàn)示例

    本文主要介紹了Maven坐標(biāo)和依賴的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • Maven學(xué)習(xí)教程之搭建多模塊企業(yè)級(jí)項(xiàng)目

    Maven學(xué)習(xí)教程之搭建多模塊企業(yè)級(jí)項(xiàng)目

    本篇文章主要介紹了Maven學(xué)習(xí)教程之搭建多模塊企業(yè)級(jí)項(xiàng)目 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • java 流與 byte[] 的互轉(zhuǎn)操作

    java 流與 byte[] 的互轉(zhuǎn)操作

    這篇文章主要介紹了java 流與 byte[] 的互轉(zhuǎn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java算法之最長(zhǎng)公共子序列問題(LCS)實(shí)例分析

    Java算法之最長(zhǎng)公共子序列問題(LCS)實(shí)例分析

    這篇文章主要介紹了Java算法之最長(zhǎng)公共子序列問題(LCS),結(jié)合實(shí)例形式分析了最長(zhǎng)公共子序列的原理及問題解決方法,需要的朋友可以參考下
    2017-11-11
  • IKAnalyzer使用不同版本中文分詞的切詞方式實(shí)現(xiàn)相同功能效果

    IKAnalyzer使用不同版本中文分詞的切詞方式實(shí)現(xiàn)相同功能效果

    今天小編就為大家分享一篇關(guān)于IKAnalyzer使用不同版本中文分詞的切詞方式實(shí)現(xiàn)相同功能效果,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 通過實(shí)例解析spring對(duì)象生命周期

    通過實(shí)例解析spring對(duì)象生命周期

    這篇文章主要介紹了通過實(shí)例解析spring對(duì)象生命周期,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 解決springboot接入springfox-swagger2遇到的一些問題

    解決springboot接入springfox-swagger2遇到的一些問題

    這篇文章主要介紹了解決springboot接入springfox-swagger2遇到的一些問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

南昌市| 噶尔县| 合阳县| 微山县| 白山市| 西青区| 扎囊县| 托克逊县| 盐亭县| 锡林浩特市| 山西省| 上饶市| 东阿县| 海原县| 隆回县| 淳化县| 济宁市| 施甸县| 连南| 平乡县| 铅山县| 蒲城县| 鄂伦春自治旗| 二连浩特市| 辛集市| 开鲁县| 波密县| 彭山县| 内乡县| 满洲里市| 莎车县| 赤壁市| 奉节县| 留坝县| 华安县| 崇信县| 石阡县| 崇仁县| 宝鸡市| 福建省| 普兰县|