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

Springboot jar運(yùn)行時(shí)如何將jar內(nèi)的文件拷貝到文件系統(tǒng)中

 更新時(shí)間:2024年06月05日 15:51:28   作者:漣漪海洋  
因?yàn)閳?zhí)行需要,需要把jar內(nèi)templates文件夾下的的文件夾及文件加壓到宿主機(jī)器的某個(gè)路徑下,以便執(zhí)行對(duì)應(yīng)的腳本文件,這篇文章主要介紹了Springboot jar運(yùn)行時(shí)如何將jar內(nèi)的文件拷貝到文件系統(tǒng)中,需要的朋友可以參考下

背景

因?yàn)閳?zhí)行需要,需要把jar內(nèi)templates文件夾下的的文件夾及文件加壓到宿主機(jī)器的某個(gè)路徑下, 以便執(zhí)行對(duì)應(yīng)的腳本文件

PS: 通過(guò)類加載器等方式,直接getFile遍歷文件,在idea中運(yùn)行是沒(méi)問(wèn)題的,但是當(dāng)打包成jar運(yùn)行就會(huì)出現(xiàn)問(wèn)題,因?yàn)閖ar內(nèi)文件的路徑不是真實(shí)路徑,會(huì)出現(xiàn)異常

java.io.FileNotFoundException: class path resource [xxx/xxx/] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:xxx.jar!/BOOT-INF/classes!/xxx/xxx

方式一 

知道文件名的情況下,無(wú)需一層一層的遍歷,將文件路徑都指定好,然后根據(jù)流文件拷貝

package com.aimsphm.practice;
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
@Component
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    @Value("${customer.config.data-root:/usr/data/}")
    private String dataRoot;
    @PostConstruct
    public void initDatabase() {
        dataRoot = dataRoot.endsWith("/") ? dataRoot : dataRoot + "/";
        List<String> fileList = getFiles();
        fileList.stream().filter(x -> !ObjectUtils.isEmpty(x)).forEach(x -> {
            try {
                URL resource = App.class.getClassLoader().getResource(x);
                InputStream inputStream = resource.openStream();
                if (ObjectUtils.isEmpty(inputStream)) {
                    return;
                }
                File file = new File(dataRoot + x);
                if (!file.exists()) {
                    FileUtils.copyInputStreamToFile(inputStream, file);
                }
            } catch (IOException e) {
                log.error("失敗:",e)
            }
        });
    }
    private List<String> getFiles() {
        return Lists.newArrayList(
                "db/practice.db",
                "local-data/0/p-1.jpg",
                "local-data/0/p-2.jpg",
                "local-data/0/p-3.jpg",
                "local-data/0/p-4.jpg",
                "local-data/1/meter-1.png",
                "local-data/-1/yw-1.png",
                "local-data/sound/test.txt",
                "local-data/multi/1/meter-multi.jpg",
                "local-data/multi/-1/yewei.png",
                "");
    }
}

方式二

通過(guò)resource的方式,獲取文件的描述信息,然后根據(jù)描述信息,獲取文件的路徑信息,然后通過(guò)拷貝流文件,將文件最終拷貝到指定的路徑下

package com.example.demo.test;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * 復(fù)制resource文件、文件夾
 *
 * @author MILLA
 */
@Component
@Slf4j
public class JarFileUtil {
    public void copyFolderFromJar() throws IOException {
        this.copyFolderFromJar("templates", "/usr/data/files");
    }
    /**
     * 復(fù)制path目錄下所有文件到指定的文件系統(tǒng)中
     *
     * @param path    文件目錄 不能以/開(kāi)頭
     * @param newPath 新文件目錄
     */
    public void copyFolderFromJar(String path, String newPath) throws IOException {
        path = preOperation(path, newPath);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        //獲取所有匹配的文件(包含根目錄文件、子目錄、子目錄下的文件)
        Resource[] resources = resolver.getResources("classpath:" + path + "/**");
        //打印有多少文件
        for (Resource resource : resources) {
            //文件名
            //以jar包運(yùn)行時(shí),不能使用resource.getFile()獲取文件路徑、判斷是否為文件等,會(huì)報(bào)錯(cuò):
            //java.io.FileNotFoundException: class path resource [xxx/xxx/] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:xxx.jar!/BOOT-INF/classes!/xxx/xxx
            //文件路徑
            //file [/xxx/xxx]
            String description = resource.getDescription();
            description = description.replace("\\", "/");
            description = description.replace(path, "/");
            //保留 /xxx/xxx
            description = description.replaceAll("(.*\\[)|(]$)", "").trim();
            //以“文件目錄”進(jìn)行分割,獲取文件相對(duì)路徑
            //獲取文件相對(duì)路徑,/xxx/xxx
            //新文件路徑
            String newFilePath = newPath + "/" + description;
            if (newFilePath.endsWith("/")) {
                File file = new File(newFilePath);
                //文件夾
                if (file.exists()) {
                    boolean mkdir = file.mkdir();
                    log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", newFilePath, mkdir);
                }
            } else {
                //文件
                InputStream stream = resource.getInputStream();
                write2File(stream, newFilePath);
            }
        }
    }
    /**
     * 文件預(yù)處理
     *
     * @param path    原文件路徑
     * @param newPath 目標(biāo)路徑
     * @return 新的路徑字符串
     */
    private static String preOperation(String path, String newPath) {
        if (!new File(newPath).exists()) {
            boolean mkdir = new File(newPath).mkdir();
            log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", newPath, mkdir);
        }
        if (path.contains("\\")) {
            path = path.replace("\\", "/");
        }
        //保證沒(méi)有重復(fù)的/出現(xiàn)
        path = path.replaceAll("(?<!\\G/|[^/])/+", "");
        if (path.startsWith("/")) {
            //以/開(kāi)頭,去掉/
            path = path.substring(1);
        }
        if (path.endsWith("/")) {
            //以/結(jié)尾,去掉/
            path = path.substring(0, path.length() - 1);
        }
        return path;
    }
    /**
     * 輸入流寫入文件
     *
     * @param is       輸入流
     * @param filePath 文件保存目錄路徑
     * @throws IOException IOException
     */
    public static void write2File(InputStream is, String filePath) throws IOException {
        File destFile = new File(filePath);
        File parentFile = destFile.getParentFile();
        boolean mkdirs = parentFile.mkdirs();
        log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", filePath, mkdirs);
        if (!destFile.exists()) {
            boolean newFile = destFile.createNewFile();
            log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", destFile.getPath(), newFile);
        }
        OutputStream os = new FileOutputStream(destFile);
        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();
    }
    public static void main(String[] args) throws IOException {
        //文件夾復(fù)制
        String path = "templates";
        String newPath = "D:/tmp";
        new JarFileUtil().copyFolderFromJar(path, newPath);
    }
}

 如果開(kāi)發(fā)中使用一些文件操作依賴,可簡(jiǎn)化代碼如下

<!--文件依賴 --> 
<dependency>
     <groupId>commons-fileupload</groupId>
     <artifactId>commons-fileupload</artifactId>
     <version>1.3.3</version>
 </dependency>
package com.example.demo.test;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.File;
/**
 * <p>
 * 功能描述:
 * </p>
 *
 * @author MILLA
 * @version 1.0
 * @since 2024/05/31 16:30
 */
@Slf4j
@Component
public class JarFileUtil{
    public static void main(String[] args) {
        JarFileUtilinit = new JarFileUtil();
        init.copyFile2Temp("http://templates//shell//", "/usr/data/shell/files");
    }
    @PostConstruct
    public void copyFile2Temp() {
    }
    public void copyFile2Temp(String source, String target) {
        try {
            source = preOperation(source, target);
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(source + "/**");
            for (int i = 0; i < resources.length; i++) {
                Resource resource = resources[i];
//                resource.getFile() jar運(yùn)行時(shí)候不能用該方法獲取文件,因?yàn)閖ar的路徑不對(duì)
                String description = resource.getDescription();
                description = description.replace("\\", "/");
                description = description.replace(source, "/");
                //保留 /xxx/xxx
                description = description.replaceAll("(.*\\[)|(]$)", "").trim();
                //以“文件目錄”進(jìn)行分割,獲取文件相對(duì)路徑
                //獲取文件相對(duì)路徑,/xxx/xxx
                //新文件路徑
                String newFilePath = target + File.separator + description;
                File file = new File(newFilePath);
                if (newFilePath.endsWith("/")) {
                    boolean mkdirs = file.mkdirs();
                    log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", newFilePath, mkdirs);
                } else {
                    FileUtils.copyInputStreamToFile(resource.getInputStream(), file);
                }
            }
        } catch (Exception e) {
            log.error("文件拷貝異常:", e);
        }
    }
    private static String preOperation(String source, String target) {
        if (!new File(target).exists()) {
            boolean mkdir = new File(target).mkdir();
            log.debug("路徑[{}]創(chuàng)建是否成功狀態(tài):{} ", target, mkdir);
        }
        if (source.contains("\\")) {
            source = source.replace("\\", "/");
        }
        //保證沒(méi)有重復(fù)的/出現(xiàn)
        source = source.replaceAll("(?<!\\G/|[^/])/+", "");
        if (source.startsWith("/")) {
            //以/開(kāi)頭,去掉/
            source = source.substring(1);
        }
        if (source.endsWith("/")) {
            //以/結(jié)尾,去掉/
            source = source.substring(0, source.length() - 1);
        }
        return source;
    }
}

 通過(guò)這種方式,就能將正在運(yùn)行的jar中的文件,拷貝到指定的路徑下,記錄備查

到此這篇關(guān)于Springboot jar運(yùn)行時(shí)如何將jar內(nèi)的文件拷貝到文件系統(tǒng)中的文章就介紹到這了,更多相關(guān)Springboot jar運(yùn)行文件拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot集成ClickHouse及應(yīng)用場(chǎng)景分析

    Springboot集成ClickHouse及應(yīng)用場(chǎng)景分析

    這篇文章主要介紹了Springboot集成ClickHouse的實(shí)例代碼,本文通過(guò)應(yīng)用場(chǎng)景實(shí)例代碼介紹了整合springboot的詳細(xì)過(guò)程,感興趣的朋友跟隨小編一起看看吧
    2022-02-02
  • spring boot+thymeleaf+bootstrap實(shí)現(xiàn)后臺(tái)管理系統(tǒng)界面

    spring boot+thymeleaf+bootstrap實(shí)現(xiàn)后臺(tái)管理系統(tǒng)界面

    這篇文章主要為大家詳細(xì)介紹了spring boot+thymeleaf+bootstrap簡(jiǎn)單實(shí)現(xiàn)后臺(tái)管理系統(tǒng)界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • SpringBoot加載讀取配置文件過(guò)程詳細(xì)分析

    SpringBoot加載讀取配置文件過(guò)程詳細(xì)分析

    在實(shí)際的項(xiàng)目開(kāi)發(fā)過(guò)程中,我們經(jīng)常需要將某些變量從代碼里面抽離出來(lái),放在配置文件里面,以便更加統(tǒng)一、靈活的管理服務(wù)配置信息。所以本文將為大家總結(jié)一下SpringBoot加載配置文件的常用方式,需要的可以參考一下
    2023-01-01
  • MyBatis OGNL 表達(dá)式的避坑指南

    MyBatis OGNL 表達(dá)式的避坑指南

    本文主要介紹了MyBatis OGNL 表達(dá)式的避坑指南,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 解決mybatis 中collection嵌套collection引發(fā)的bug

    解決mybatis 中collection嵌套collection引發(fā)的bug

    這篇文章主要介紹了解決mybatis 中collection嵌套collection引發(fā)的bug,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • SpringBoot+Vue+Element-ui實(shí)現(xiàn)前后端分離

    SpringBoot+Vue+Element-ui實(shí)現(xiàn)前后端分離

    使用前后端分離的方式,可以減少代碼耦合,本文主要介紹了SpringBoot+Vue+Element-ui實(shí)現(xiàn)前后端分離,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • idea 安裝 Mybatis 開(kāi)發(fā)幫助插件 MyBatisCodeHelper-Pro 插件破解版的方法

    idea 安裝 Mybatis 開(kāi)發(fā)幫助插件 MyBatisCodeHelper-Pro 插件破解版的方法

    MyBatisCodeHelper-Pro 插件可以幫助我們快速的開(kāi)發(fā) mybatis,這篇文章給大家介紹idea 安裝 Mybatis 開(kāi)發(fā)幫助插件 MyBatisCodeHelper-Pro 插件破解版的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2020-09-09
  • java對(duì)圖片進(jìn)行壓縮和resize縮放的方法

    java對(duì)圖片進(jìn)行壓縮和resize縮放的方法

    本篇文章主要介紹了java對(duì)圖片進(jìn)行壓縮和resize調(diào)整的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解

    java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解

    這篇文章主要為大家介紹了java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • JAVA注解代碼詳解一篇就夠了

    JAVA注解代碼詳解一篇就夠了

    這篇文章主要介紹了Java注解詳細(xì)介紹,本文講解了Java注解是什么、Java注解基礎(chǔ)知識(shí)、Java注解類型、定義Java注解類型的注意事項(xiàng)等內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評(píng)論

永兴县| 浑源县| 厦门市| 威海市| 彰化市| 嘉峪关市| 郓城县| 龙游县| 浦北县| 军事| 武平县| 德江县| 盐池县| 安平县| 辽宁省| 礼泉县| 卓资县| 博爱县| 常德市| 色达县| 若羌县| 新建县| 含山县| 淮阳县| 襄樊市| 武城县| 蒙山县| 临武县| 外汇| 鹿邑县| 饶阳县| 游戏| 阿合奇县| 阿拉尔市| 六安市| 龙陵县| 大竹县| 巩义市| 兴业县| 德化县| 哈密市|