专栏首页歪脖贰点零SpringBoot项目构建成jar运行,如何正确读取resource里的文件

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

不管你使用的是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

本文分享自微信公众号 - 歪脖贰点零(growithus),作者:guooo

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 破解程序员晋升痛点

    这是一张程序员职业生涯理想的发展走向图(图中坡度仅靠参考),至于你后续成长到某个阶段,转向业务方向或管理方向发展,不在本文讨论之列。

    歪脖贰点零
  • 基于SpringCloud的Microservices架构实战案例-在线API管理

    前端和后端的唯一联系,变成了API接口;API文档变成了前后端开发人员联系的纽带,变得越来越重要,swagger就是一款让你更好的书写API文档的框架。 本实战...

    歪脖贰点零
  • 工程师们要小心所谓的"全栈",也有可能是个陷阱

    论坛里看到的这个帖子,访问量过万,回复近200条,还是能引见大家共情的。小公司中这样的情况屡见不鲜,为了节省成本,每个人都需要是多面手,生存现状压迫必然需要节省...

    歪脖贰点零
  • [logstash-input-file]插件使用详解

      前篇介绍过Logstash的使用,本篇继续深入,介绍下最常用的input插件——file。   这个插件可以从指定的目录或者文件读取内容,输入到管道处理...

    用户1154259
  • 【Java 面试题系列 02】== 和 equals 的区别

    代码分析:因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而 new Integer( )方法则重新开辟了内存空间,所以 == 结果为 fal...

    方才编程_公众号同名
  • gh0st源码分析与远控的编写(三)

        好久不见。距离上次写gh0st来有好久了,一是期末考试,忙不开,二是后来电脑坏了,几天没能上网。

    phith0n
  • 基于R语言的梯度推进算法介绍

    简介 通常来说,我们可以从两个方面来提高一个预测模型的准确性:完善特征工程(feature engineering)或是直接使用Boosting算法。通过大量数...

    CDA数据分析师
  • Argo AI发布了第三代自动驾驶汽车,测试范围扩大

    自动驾驶汽车创业公司Argo由前谷歌和优步自主技术部门的高管创立,今天推出了第三代测试车辆:改进的福特Fusion Hybrids汽车。

    AiTechYun
  • Effective.Java 读书笔记(8)关于equals方法

    重写equals看上去十分简单对吧,但是我觉得很多时候重写equals可能会招致一些问题,这些问题有时可能会特别严重,当然了不重写不就完事了吗?但是这只适用于那...

    Mezereon
  • 读取文件

    读取文件是一个经常用到的功能,比如从文件目录中读取一张照片,读取一个txt文件,word,excel等等,今天我们就学习一下go是如何读取文件的?

    酷走天涯

扫码关注云+社区

领取腾讯云代金券