首頁  >  文章  >  Java  >  springboot怎麼實作jar運行複製resources檔案到指定的目錄

springboot怎麼實作jar運行複製resources檔案到指定的目錄

PHPz
PHPz轉載
2023-05-12 21:34:041598瀏覽

springboot實作 jar運行複製resources檔案到指定的目錄

1.需求

在專案開發過程中需要將專案resources/static/目錄下所有資源複製到指定目錄。公司專案中需要下載影片文件,由於下載的有html頁面,對多路影片進行畫面加載,用到對應的靜態資源文件,如js,css.jwplayer,jquery.js等文件

# maven打成的jar和平時發布的專案路徑不通,所以在讀取路徑的時候獲取的是jar的路徑,無法獲取jar裡面的檔案路徑

#2.思路

根據我的需求,複製的想法大概是,先獲取到resources/static/blog目錄下文件清單,然後通過清單,循環將文件複製到指定位置(相對路徑需要確保一致)

因為項目會被打成jar包,所以不能用傳統的目錄文件複製方式,這裡需要用到Spring Resource:

#Resource接口,簡單說是整個Spring框架對資源的抽象存取接口。它繼承於InputStreamSource介面。後續文章會詳細的分析。

Resource介面的方法說明:

##說明exists()判斷資源是否存在,true表示存在。 isReadable()判斷資源的內容是否可讀。需要注意的是當其結果為true的時候,其內容未必真的可讀,但如果返回false,則其內容必定不可讀。 isOpen()判斷目前Resource代表的底層資源是否已打開,如果傳回true,只能被讀取一次然後關閉以避免資源外洩;此方法主要針對InputStreamResource,實作類別中只有它的回傳結果為true,其他都為false。 getURL()傳回目前資源對應的URL。如果目前資源不能解析為一個URL則會拋出例外。如ByteArrayResource就不能解析為一個URL。 getURI()傳回目前資源對應的URI。如果目前資源不能解析為一個URI則會拋出異常。 getFile()傳回目前資源對應的File。 contentLength()回傳目前資源內容的長度##lastModified()createRelative()getFilename()getDescription()getInputStream()來取得Resource清單,我需要透過ResourceLoader介面取得資源,在這裡我選擇了
#方法
傳回目前Resource代表的底層資源的最後修改時間。
根據資源的相對路徑建立新資源。 [預設不支援建立相對路徑資源]
#取得資源的檔案名稱。
傳回目前資源底層資源的描述符,通常就是資源的全路徑(實際檔案名稱或實際URL位址)。
取得目前資源代表的輸入流。除了InputStreamResource實作類別以外,其它Resource實作類別每次呼叫getInputStream()方法都會傳回一個全新的InputStream。

org.springframework.core.io.support.PathMatchingResourcePatternResolver

3. 實作程式碼

/**
     * 只复制下载文件中用到的js
     */
    private void copyJwplayer() {
        //判断指定目录下文件是否存在
        ApplicationHome applicationHome = new ApplicationHome(getClass());
        String rootpath = applicationHome.getSource().getParentFile().toString();
        String realpath=rootpath+"/vod/jwplayer/";   //目标文件
        String silderrealpath=rootpath+"/vod/jwplayer/silder/";   //目标文件
        String historyrealpath=rootpath+"/vod/jwplayer/history/";   //目标文件
        String jwplayerrealpath=rootpath+"/vod/jwplayer/jwplayer/";   //目标文件
        String layoutrealpath=rootpath+"/vod/jwplayer/res/layout/";   //目标文件
        /**
         * 此处只能复制目录中的文件,不能多层目录复制(目录中的目录不能复制,如果循环复制目录中的目录则会提示cannot be resolved to URL because it does not exist)
         */
        //不使用getFileFromClassPath()则报[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/");  //复制目录
        FreeMarkerUtil.BatCopyFileFromJar(fileFromClassPath.toString(),realpath);
        //silder
        File flvjspath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/silder/");  //复制目录
        FreeMarkerUtil.BatCopyFileFromJar(flvjspath.toString(),silderrealpath);
        //history
        File historypath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/history/");  //复制目录
        FreeMarkerUtil.BatCopyFileFromJar(historypath.toString(),historyrealpath);
        //jwplayer
        File jwplayerpath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/jwplayer/");  //复制目录
        FreeMarkerUtil.BatCopyFileFromJar(jwplayerpath.toString(),jwplayerrealpath);
        //layout
        File layoutpath = FreeMarkerUtil.getFileFromClassPath("/static/jwplayer/res/layout/");  //复制目录
        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 {

   
    /**
     * 复制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运行时,resource.getFile().isFile() 无法获取文件类型,会报异常,抓取异常后直接生成新的文件即可;以非jar运行时,需要判断文件类型,避免如果是目录会复制错误,将目录写成文件。
                    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();
        }
    }
    /**
     * 创建文件
     * @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();
    }
    /**
    *处理异常报错(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(); // 关闭流
                    } catch (IOException e) {
                    }
                }
                if (outStream != null) {
                    try {
                        outStream.close(); // 关闭流
                    } catch (IOException e) {
                    }
                }
            }
        }
        return targetFile;
    }
}

5.效果

##

以上是springboot怎麼實作jar運行複製resources檔案到指定的目錄的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除