springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄(思路詳解)
springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄
1. 需求
在項(xiàng)目開發(fā)過程中需要將項(xiàng)目resources/static/目錄下所有資源資源復(fù)制到指定目錄。公司項(xiàng)目中需要下載視頻文件,由于下載的有個(gè)html頁面,對(duì)多路視頻進(jìn)行畫面加載,用到對(duì)應(yīng)的靜態(tài)資源文件,如js,css.jwplayer,jquery.js等文件
maven打成的jar和平時(shí)發(fā)布的項(xiàng)目路徑不通,所以在讀取路徑的時(shí)候獲取的是jar的路徑,無法獲取jar里面的文件路徑
2. 思路
根據(jù)我的需求,復(fù)制的思路大概是,先獲取到resources/static/blog目錄下文件清單,然后通過清單,循環(huán)將文件復(fù)制到指定位置(相對(duì)路徑需要確保一致)
因?yàn)轫?xiàng)目會(huì)被打成jar包,所以不能用傳統(tǒng)的目錄文件復(fù)制方式,這里需要用到Spring Resource:
Resource接口,簡單說是整個(gè)Spring框架對(duì)資源的抽象訪問接口。它繼承于InputStreamSource接口。后續(xù)文章會(huì)詳細(xì)的分析。
Resource接口的方法說明:
方法 | 說明 |
---|---|
exists() | 判斷資源是否存在,true表示存在。 |
isReadable() | 判斷資源的內(nèi)容是否可讀。需要注意的是當(dāng)其結(jié)果為true的時(shí)候,其內(nèi)容未必真的可讀,但如果返回false,則其內(nèi)容必定不可讀。 |
isOpen() | 判斷當(dāng)前Resource代表的底層資源是否已經(jīng)打開,如果返回true,則只能被讀取一次然后關(guān)閉以避免資源泄露;該方法主要針對(duì)于InputStreamResource,實(shí)現(xiàn)類中只有它的返回結(jié)果為true,其他都為false。 |
getURL() | 返回當(dāng)前資源對(duì)應(yīng)的URL。如果當(dāng)前資源不能解析為一個(gè)URL則會(huì)拋出異常。如ByteArrayResource就不能解析為一個(gè)URL。 |
getURI() | 返回當(dāng)前資源對(duì)應(yīng)的URI。如果當(dāng)前資源不能解析為一個(gè)URI則會(huì)拋出異常。 |
getFile() | 返回當(dāng)前資源對(duì)應(yīng)的File。 |
contentLength() | 返回當(dāng)前資源內(nèi)容的長度 |
lastModified() | 返回當(dāng)前Resource代表的底層資源的最后修改時(shí)間。 |
createRelative() | 根據(jù)資源的相對(duì)路徑創(chuàng)建新資源。[默認(rèn)不支持創(chuàng)建相對(duì)路徑資源] |
getFilename() | 獲取資源的文件名。 |
getDescription() | 返回當(dāng)前資源底層資源的描述符,通常就是資源的全路徑(實(shí)際文件名或?qū)嶋HURL地址)。 |
getInputStream() | 獲取當(dāng)前資源代表的輸入流。除了InputStreamResource實(shí)現(xiàn)類以外,其它Resource實(shí)現(xiàn)類每次調(diào)用getInputStream()方法都將返回一個(gè)全新的InputStream。 |
獲取Resource清單,我需要通過ResourceLoader接口獲取資源,在這里我選擇了
org.springframework.core.io.support.PathMatchingResourcePatternResolver
3. 實(shí)現(xiàn)代碼
/** * 只復(fù)制下載文件中用到的js */ private void copyJwplayer() { //判斷指定目錄下文件是否存在 ApplicationHome applicationHome = new ApplicationHome(getClass()); String rootpath = applicationHome.getSource().getParentFile().toString(); String realpath=rootpath+"/vod/jwplayer/"; //目標(biāo)文件 String silderrealpath=rootpath+"/vod/jwplayer/silder/"; //目標(biāo)文件 String historyrealpath=rootpath+"/vod/jwplayer/history/"; //目標(biāo)文件 String jwplayerrealpath=rootpath+"/vod/jwplayer/jwplayer/"; //目標(biāo)文件 String layoutrealpath=rootpath+"/vod/jwplayer/res/layout/"; //目標(biāo)文件 /** * 此處只能復(fù)制目錄中的文件,不能多層目錄復(fù)制(目錄中的目錄不能復(fù)制,如果循環(huán)復(fù)制目錄中的目錄則會(huì)提示cannot be resolved to URL because it does not exist) */ //不使用getFileFromClassPath()則報(bào)[static/jwplayerF:/workspace/VRSH265/target/classes/static/jwplayer/flvjs/] cannot be resolved to URL because it does not exist //jwplayer File fileFromClassPath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/"); //復(fù)制目錄 FreeMarkerUtil.BatCopyFileFromJar(fileFromClassPath.toString(),realpath); //silder File flvjspath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/silder/"); //復(fù)制目錄 FreeMarkerUtil.BatCopyFileFromJar(flvjspath.toString(),silderrealpath); //history File historypath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/history/"); //復(fù)制目錄 FreeMarkerUtil.BatCopyFileFromJar(historypath.toString(),historyrealpath); //jwplayer File jwplayerpath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/jwplayer/"); //復(fù)制目錄 FreeMarkerUtil.BatCopyFileFromJar(jwplayerpath.toString(),jwplayerrealpath); //layout File layoutpath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/res/layout/"); //復(fù)制目錄 FreeMarkerUtil.BatCopyFileFromJar(layoutpath.toString(),layoutrealpath); }
4. 工具類FreeMarkerUtil
package com.aio.util; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import java.io.*; /** * @author:hahaha * @creattime:2021-12-02 10:33 */ public class FreeMarkerUtil { /** * 復(fù)制path目錄下所有文件 * @param path 文件目錄 不能以/開頭 * @param newpath 新文件目錄 */ public static void BatCopyFileFromJar(String path,String newpath) { if (!new File(newpath).exists()){ new File(newpath).mkdir(); } ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { //獲取所有匹配的文件 Resource[] resources = resolver.getResources(path+"/*"); //打印有多少文件 for(int i=0;i<resources.length;i++) { Resource resource=resources[i]; try { //以jar運(yùn)行時(shí),resource.getFile().isFile() 無法獲取文件類型,會(huì)報(bào)異常,抓取異常后直接生成新的文件即可;以非jar運(yùn)行時(shí),需要判斷文件類型,避免如果是目錄會(huì)復(fù)制錯(cuò)誤,將目錄寫成文件。 if(resource.getFile().isFile()) { makeFile(newpath+"/"+resource.getFilename()); InputStream stream = resource.getInputStream(); write2File(stream, newpath+"/"+resource.getFilename()); } }catch (Exception e) { makeFile(newpath+"/"+resource.getFilename()); InputStream stream = resource.getInputStream(); write2File(stream, newpath+"/"+resource.getFilename()); } } } catch (Exception e) { e.printStackTrace(); } } /** * 創(chuàng)建文件 * @param path 全路徑 指向文件 * @return */ public static boolean makeFile(String path) { File file = new File(path); if(file.exists()) { return false; } if (path.endsWith(File.separator)) { return false; } if(!file.getParentFile().exists()) { if(!file.getParentFile().mkdirs()) { return false; } } try { if (file.createNewFile()) { return true; } else { return false; } } catch (IOException e) { e.printStackTrace(); return false; } } /** * 輸入流寫入文件 * * @param is * 輸入流 * @param filePath * 文件保存目錄路徑 * @throws IOException */ public static void write2File(InputStream is, String filePath) throws IOException { OutputStream os = new FileOutputStream(filePath); int len = 8192; byte[] buffer = new byte[len]; while ((len = is.read(buffer, 0, len)) != -1) { os.write(buffer, 0, len); } os.close(); is.close(); } /** *處理異常報(bào)錯(cuò)(springboot讀取classpath里的文件,解決打jar包java.io.FileNotFoundException: class path resource cannot be opened) **/ public static File getFileFromClassPath(String path){ File targetFile = new File(path); if(!targetFile.exists()){ if(targetFile.getParent()!=null){ File parent=new File(targetFile.getParent()); if(!parent.exists()){ parent.mkdirs(); } } InputStream initialStream=null; OutputStream outStream =null; try { Resource resource=new ClassPathResource(path); //注意通過getInputStream,不能用getFile initialStream=resource.getInputStream(); byte[] buffer = new byte[initialStream.available()]; initialStream.read(buffer); outStream = new FileOutputStream(targetFile); outStream.write(buffer); } catch (IOException e) { } finally { if (initialStream != null) { try { initialStream.close(); // 關(guān)閉流 } catch (IOException e) { } } if (outStream != null) { try { outStream.close(); // 關(guān)閉流 } catch (IOException e) { } } } } return targetFile; } }
5.效果
到此這篇關(guān)于springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄的文章就介紹到這了,更多相關(guān)springboot運(yùn)行復(fù)制resources文件到指定的目錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot 項(xiàng)目讀取Resources目錄下的文件(推薦)
- 解決springboot項(xiàng)目找不到resources目錄下的資源問題
- 解決@springboottest注解無法加載src/main/resources目錄下文件
- springboot項(xiàng)目讀取resources目錄下的文件的9種方式
- SpringBoot中讀取jar包中的resources目錄下的文件的三種方式
- SpringBoot如何讀取resources目錄下的文件
- SpringBoot實(shí)現(xiàn)本地上傳文件到resources目錄
- Springboot獲取jar包中resources資源目錄下的文件
- Springboot項(xiàng)目啟動(dòng)不加載resources目錄下的文件問題
- SpringBoot下獲取resources目錄下文件的常用方法
相關(guān)文章
Netty分布式高性能工具類recycler的使用及創(chuàng)建
這篇文章主要為大家介紹了Netty分布式高性能工具類recycler的使用和創(chuàng)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03Java基礎(chǔ)-Java的體系結(jié)構(gòu)
這篇文章主要介紹了Java的體系結(jié)構(gòu),Java幾乎成為了“開源”的代名詞。第三方開源軟件和框架。如Tomcat、Struts,MyBatis,Spring等,下面我們來看看文章具體的內(nèi)容介紹吧2022-01-01Spring Boot Admin 進(jìn)行項(xiàng)目監(jiān)控管理的方法
Spring Boot Admin是一個(gè)開源社區(qū)項(xiàng)目,用于管理和監(jiān)控SpringBoot應(yīng)用程序。 這篇文章主要介紹了 Spring Boot Admin 進(jìn)行項(xiàng)目監(jiān)控管理的方法,需要的朋友可以參考下2020-07-07淺談Java內(nèi)部類——靜態(tài)內(nèi)部類
這篇文章主要介紹了Java靜態(tài)內(nèi)部類的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java內(nèi)部類的相關(guān)知識(shí),感興趣的朋友可以了解下2020-08-08如何基于java向mysql數(shù)據(jù)庫中存取圖片
這篇文章主要介紹了如何基于java向mysql數(shù)據(jù)庫中存取圖片,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02SpringMVC MVC架構(gòu)與Servlet使用詳解
MVC設(shè)計(jì)模式一般指 MVC 框架,M(Model)指數(shù)據(jù)模型層,V(View)指視圖層,C(Controller)指控制層。使用 MVC 的目的是將 M 和 V 的實(shí)現(xiàn)代碼分離,使同一個(gè)程序可以有不同的表現(xiàn)形式。其中,View 的定義比較清晰,就是用戶界面2022-10-10springboot application.properties 文件注入數(shù)組方式
這篇文章主要介紹了springboot application.properties 文件注入數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11idea報(bào)錯(cuò):程序包org.springframework.web.bind.annotation不存在
在用本地的maven倉庫的時(shí)候會(huì)org.springframework.web.bind.annotation不存在的錯(cuò)誤,本文就詳細(xì)的介紹一下解決方法,感興趣的可以了解下2023-08-08