springboot 项目打成jar包导致resources 下的文件无法读取

在idea 里面springboot项目跑的好好得,resources 下面的.ftl文件和其他的图片啥的读取都好好的,没什么问题,但是打成jar包用命令跑就会出问题,报java.io.FileNotFoundException: 错误。我的解决方案目前来看可以解决,但是不完美,希望看到有更好的解决方案。
如图:resources 下面有.ftl 模板和.jpg 文件等
在这里插入图片描述
在idea里面跑的时候读取可能是这样的,没什么问题

Image image =Image.getInstance("src/main/resources/image/image.png");

但是打成jar 包后,这个路径是有问题的,会报文件找不到错误
或者这种获取.ftl文件的方式,在打成jar包后运行依旧报错。

 File file = new File(ClassLoader.getSystemResource("templates/mytemplate.ftl").getPath());

解决方案:
先说原因吧,我的理解是文件打包后都在jar 文件里面,所以获取的时候路径有点问题,找到了一个方法就是把源文件复制出来io写入到指定的路径,然后利用复制出来的文件,下面是我的代码

 package mybatisplus.google.freemaker;

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 包: mybatisplus.google.freemaker
 * 作者: climber.luo
 * 时间:2020.08.29 15:19
 */
public class FreeMakerUtil {
    // 临时目录  resource 文件只生成一次  这个路径可以换成虚拟机上的实际存在的路径
    static String tempPath =  "G:/study/templates/mytemplate.ftl";
    static File f = new File(tempPath);
    //  创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
    private static final Configuration configuration;

    static {
        configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        configuration.setDefaultEncoding("utf-8");
        ClassPathResource resource = new ClassPathResource("templates/mytemplate.ftl");
        if (!f.exists()) {
            try {
                new File(f.getParent()).mkdirs();
                InputStream inputStream = resource.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(f);
                IOUtils.copy(inputStream, outputStream);
                // 关闭流
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            configuration.setDirectoryForTemplateLoading(new File(f.getParent()));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Template getTemplate(String templateName) throws IOException {
        return configuration.getTemplate(templateName);
    }
}

这行代码我是很不喜欢的,固定死了,这个就是从jar 里面将文件复制出来保存的路径

static String tempPath =  "G:/study/templates/mytemplate.ftl";

关键代码

    // 临时目录  resource 文件只生成一次
    static String tempPath =  "G:/study/templates/mytemplate.ftl";
    static File f = new File(tempPath);
    // 这里是从jar包中读取文件 ,关键类
		ClassPathResource resource = new ClassPathResource("templates/mytemplate.ftl");
        if (!f.exists()) {
            try {
            // 创建文件夹
                new File(f.getParent()).mkdirs();
                //  将resources 里的文件都取成流 
                InputStream inputStream = resource.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(f);
                // 这个就是将jar 包里的文件复制到指定的文件夹里面
                IOUtils.copy(inputStream, outputStream);
                // 关闭流
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

缺点是将读取到的文件带入到系统里面,这样就回产生垃圾文件或者说零时文件,不太好,最好时有方法可以直接读取而不用产生临时文件。当然通过打包方式可以避免这个问题,但是希望这里还是希望有通过jar包也能解决这个问题的更好的方法。

本来不会发现这个问题,我在虚拟机里测试的时候发现的,记录下来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值