首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot项目构建成jar运行,如何正确读取resource里的文件

SpringBoot项目构建成jar运行,如何正确读取resource里的文件

作者头像
MavenTalker
发布2019-07-19 10:39:24
10.5K0
发布2019-07-19 10:39:24
举报
文章被收录于专栏:歪脖贰点零歪脖贰点零
不管你使用的是SpringBoot 1.x版本还是SpringBoot2.x版本,在开Dev环境中使用eclipse、IEAD、STS等IDE工具,进行resource目录下文件的获取,简单的采用@Value注解的形式就可以得到,文件读取的主知一般情况下也是没有问题的,比如
File file = ResourceUtils.getFile("classpath:exceltmp/template_export.xls");

度娘检索出来的文章也基本上告诉你,这样是没有问题的。But,使用mvn package构建成jar文件,运行后报异常如下:

ja java.io.FileNotFoundException: class path resource [
xxx] cannot be resolved to absolute file path because it does not reside in the file system:jar:...

Resource下的文件是存在于jar这个文件里面,在磁盘上是没有真实路径存在的,它其实是位于jar内部的一个路径。所以通过ResourceUtils.getFile或者this.getClass().getResource("")方法无法正确获取文件。

有一种比较偷懒的做法:将文档放在项目外,应用可以读取到的一个固定目录。按正常的方式读取即可,但可维护性比较差,很容易被误操作丢失。

文本文件读取

这种情况下可以采用流的方式来读取文件,拿到文件流再进行相关的操作。如果你使用Spring框架的话,可以采用ClassPathResource来读取文件流,将文件读取成字符串才进行二次操作,比较适用于文本文件,如properties,txt,csv,SQL,json等,代码参考:

String data = "";
ClassPathResource cpr = new ClassPathResource("static/file.txt");
try {
    byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
    data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
    LOG.warn("IOException", e);
}

这里提供一个工具类来帮助大家读取文件:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

import org.springframework.core.io.ClassPathResource;

public final class ClassPathResourceReader {
    /**
     * path:文件路径
     * @since JDK 1.8
     */
    private final String path;

    /**
     * content:文件内容
     * @since JDK 1.6
     */
    private String content;

    public ClassPathResourceReader(String path) {
        this.path = path;
    }

    public String getContent() {
        if (content == null) {
            try {
                ClassPathResource resource = new ClassPathResource(path);
                BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
                content = reader.lines().collect(Collectors.joining("\n"));
                reader.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
        return content;
    }
}

使用方式也是相当简单

String content = new ClassPathResourceReader("log4j.properties").getContent();

非文本文件读取

更多的情况是读取非文本文件,比如xls,还是希望拿到一个文件,再去解析使用。参考代码如下:

ClassPathResource classPathResource = new ClassPathResource("exceltmp/template_export.xls"");

InputStream inputStream = classPathResource.getInputStream();
//生成目标文件
File somethingFile = File.createTempFile("template_export_copy", ".xls");
try {
    FileUtils.copyInputStreamToFile(inputStream, somethingFile);
} finally {
    IOUtils.closeQuietly(inputStream);
}

拿到目标文件后,再按照正常的取法如ResourceUtils.getFile,读取即可。

参考文章:

https://stackoverflow.com/questions/25869428/classpath-resource-not-found-when-running-as-jar

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MavenTalk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文本文件读取
  • 非文本文件读取
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档