欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

背景

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

PS: 通過類加載器等方式,直接getFile遍歷文件,在idea中運行是沒問題的,但是當打包成jar運行就會出現(xiàn)問題,因為jar內(nèi)文件的路徑不是真實路徑,會出現(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

方式一 

知道文件名的情況下,無需一層一層的遍歷,將文件路徑都指定好,然后根據(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",
                "");
    }
}

方式二

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

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    文件目錄 不能以/開頭
     * @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包運行時,不能使用resource.getFile()獲取文件路徑、判斷是否為文件等,會報錯:
            //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();
            //以“文件目錄”進行分割,獲取文件相對路徑
            //獲取文件相對路徑,/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 目標路徑
     * @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("\\", "/");
        }
        //保證沒有重復(fù)的/出現(xiàn)
        path = path.replaceAll("(?<!\\G/|[^/])/+", "");
        if (path.startsWith("/")) {
            //以/開頭,去掉/
            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);
    }
}

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

<!--文件依賴 --> 
<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運行時候不能用該方法獲取文件,因為jar的路徑不對
                String description = resource.getDescription();
                description = description.replace("\\", "/");
                description = description.replace(source, "/");
                //保留 /xxx/xxx
                description = description.replaceAll("(.*\\[)|(]$)", "").trim();
                //以“文件目錄”進行分割,獲取文件相對路徑
                //獲取文件相對路徑,/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("\\", "/");
        }
        //保證沒有重復(fù)的/出現(xiàn)
        source = source.replaceAll("(?<!\\G/|[^/])/+", "");
        if (source.startsWith("/")) {
            //以/開頭,去掉/
            source = source.substring(1);
        }
        if (source.endsWith("/")) {
            //以/結(jié)尾,去掉/
            source = source.substring(0, source.length() - 1);
        }
        return source;
    }
}

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

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

相關(guān)文章

  • Java如何獲取對象屬性及對應(yīng)值

    Java如何獲取對象屬性及對應(yīng)值

    這篇文章主要介紹了Java如何獲取對象屬性及對應(yīng)值,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Java整合Redis實現(xiàn)坐標附近查詢功能

    Java整合Redis實現(xiàn)坐標附近查詢功能

    這篇文章主要介紹了Java整合Redis實現(xiàn)坐標附近查詢,我們可以在redis服務(wù)器使用命令 help xxx 查看指令的具體用法,本文給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2023-11-11
  • Spring Boot 自定義數(shù)據(jù)源DruidDataSource代碼

    Spring Boot 自定義數(shù)據(jù)源DruidDataSource代碼

    這篇文章主要介紹了Spring Boot 自定義數(shù)據(jù)源DruidDataSource代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • 淺談Spring事務(wù)傳播行為實戰(zhàn)

    淺談Spring事務(wù)傳播行為實戰(zhàn)

    這篇文章主要介紹了淺談Spring事務(wù)傳播行為實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java使用poi組件導(dǎo)出Excel格式數(shù)據(jù)

    Java使用poi組件導(dǎo)出Excel格式數(shù)據(jù)

    這篇文章主要介紹了Java使用poi組件導(dǎo)出Excel格式數(shù)據(jù),需要的朋友可以參考下
    2020-02-02
  • 手把手教你寫一個SpringBoot+gRPC服務(wù)

    手把手教你寫一個SpringBoot+gRPC服務(wù)

    本文將在本地環(huán)境下搭建gRPC客戶端和服務(wù)端,并成功建立通訊發(fā)送消息的方式,從而幫助大家深入了解gRPC在Spring Boot項目中的應(yīng)用,有需要的小伙伴可以參考下
    2023-12-12
  • Java求余%操作引發(fā)的一連串故事

    Java求余%操作引發(fā)的一連串故事

    取模運算與取余運算兩個概念有重疊的部分但又不完全一致。主要的區(qū)別在于對負整數(shù)進行除法運算時操作不同。本文重點給大家介紹Java求余%操作引發(fā)的一連串故事,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java Web項目中Spring框架處理JSON格式數(shù)據(jù)的方法

    Java Web項目中Spring框架處理JSON格式數(shù)據(jù)的方法

    Spring MVC是個靈活的框架,返回JSON數(shù)據(jù)的也有很多五花八門的方式,這里我們來整理一個最簡單的Java Web項目中Spring框架處理JSON格式數(shù)據(jù)的方法:
    2016-05-05
  • 初識Spark入門

    初識Spark入門

    這篇文章主要介紹了初識Spark入門,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • MyBatis的各種查詢功能結(jié)果接收類型的選擇(推薦)

    MyBatis的各種查詢功能結(jié)果接收類型的選擇(推薦)

    文章介紹了MyBatis中查詢結(jié)果的不同接收方式,包括單條數(shù)據(jù)和多條數(shù)據(jù)的處理方法,以及MyBatis的默認類型別名,感興趣的朋友跟隨小編一起看看吧
    2024-11-11

最新評論