溫馨提示×

溫馨提示×

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

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

如何解決SpringBoot jar包中的文件讀取問題

發(fā)布時(shí)間:2021-07-22 09:51:59 來源:億速云 閱讀:161 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“如何解決SpringBoot jar包中的文件讀取問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何解決SpringBoot jar包中的文件讀取問題”吧!

 

前言

SpringBoot微服務(wù)已成為業(yè)界主流,從開發(fā)到部署都非常省時(shí)省力,但是最近小明開發(fā)時(shí)遇到一個(gè)問題:在代碼中讀取資源文件(比如word文檔、導(dǎo)出模版等),本地開發(fā)時(shí)可以正常讀取 ,但是,當(dāng)我們打成jar包發(fā)布到服務(wù)器后,再次執(zhí)行程序時(shí)就會拋出找不到文件的異常。

 

背景

這個(gè)問題是在一次使用freemarker模版引擎導(dǎo)出word報(bào)告時(shí)發(fā)現(xiàn)的。大概說一下docx導(dǎo)出java實(shí)現(xiàn)思路:導(dǎo)出word的文檔格式為docx,事先準(zhǔn)備好一個(gè)排好版的docx文檔作為模版,讀取解析該模版,將其中的靜態(tài)資源替換再導(dǎo)出。

docx文檔本身其實(shí)是一個(gè)壓縮的zip文件,將其解壓過后就會發(fā)現(xiàn)它有自己的目錄結(jié)構(gòu)。

 

問題

這個(gè)docx文檔所在目錄如下圖所示:如何解決SpringBoot jar包中的文件讀取問題在本地調(diào)試時(shí),我使用如下方式讀?。?/p>

import org.springframework.util.ResourceUtils;
    public static void main(String[] args) throws IOException {
File docxTemplate = ResourceUtils.getFile("classpath:templates/docxTemplate.docx");
    }
 

可以正常解析使用,但是打包發(fā)布到beta環(huán)境卻不可用。拋出異常如下:

java.io.FileNotFoundException: class path resource [templates/docxTemplate.docx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/usr/local/subject-server.jar!/BOOT-INF/classes!/templates/docxTemplate.docx
 

顯而易見,這個(gè)異常告訴我們:沒有找到文件,但是將jar包解壓過后,發(fā)現(xiàn)這個(gè)文件是真真實(shí)實(shí)存在的。那這到底是怎么回事呢?這壓根難不倒我。我們要善于透過堆棧信息看本質(zhì)。通過仔細(xì)觀察堆棧信息,我發(fā)現(xiàn)此時(shí)的文件路徑并不是一個(gè)合法的URL(文件資源定位符)。原來jar包中資源有其專門的URL形式:jar:!/{entry} )。所以,此時(shí)如果仍然按照標(biāo)準(zhǔn)的文件資源定位形式

File f=new File("jar:file:……");
 

定位文件,就會拋出java.io.FileNotFoundException。

 

解決

雖然我們不能用常規(guī)操作文件的方法來讀取jar包中的資源文件docxTemplate.docx,但可以通過Class類的getResourceAsStream()方法,即通過流的方式來獲取 :

    public static void main(String[] args) throws IOException {
InputStream inputStream = WordUtil.class.getClassLoader().getResourceAsStream("templates/docxTemplate.docx");
    }
 

拿到流之后,就可以將其轉(zhuǎn)換為任意一個(gè)我們需要的對象,比如File、String等等,此處我要獲取docxTemplate.docx下的目錄結(jié)構(gòu),因此我需要一個(gè)File對象,代碼舉例如下:

import org.apache.commons.io.FileUtils;

   public static void main(String[] args) throws IOException {
        InputStream inputStream = WordUtil.class.getClassLoader().getResourceAsStream("templates/docxTemplate.docx");
        File docxFile = new File("docxTemplate.docx");
        // 使用common-io的工具類即可轉(zhuǎn)換
        FileUtils.copyToFile(inputStream,docxFile);
        ZipFile zipFile = new ZipFile(docxFile);
        Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
        // todo 記得關(guān)閉流
    }
      

結(jié)果

打包、發(fā)布至beta環(huán)境,親測可用,問題完美解決。

到此,相信大家對“如何解決SpringBoot jar包中的文件讀取問題”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI