ITPub博客

首页 > 数据库 > 数据库开发技术 > SpringBoot项目构建成jar运行,如何正确读取resource里的文件

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

原创 数据库开发技术 作者:MavenTalk 时间:2018-12-20 07:11:26 0 删除 编辑

题图:from  unsplash

不管你使用的是SpringBoot 1.x版本还是SpringBoot2.x版本,在开Dev环境中使用eclipse、IEAD、STS等IDE工具,进行resource目录下文件的获取,简单的采用@Value注解的形式就可以得到,文件读取的主知一般情况下也是没有问题的,比如

  1. 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等,代码参考:

  1. String data = "";

  2. ClassPathResource cpr = new ClassPathResource("static/file.txt");

  3. try {

  4.    byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());

  5.    data = new String(bdata, StandardCharsets.UTF_8);

  6. } catch (IOException e) {

  7.    LOG.warn("IOException", e);

  8. }

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

  1. import java.io.BufferedReader;

  2. import java.io.IOException;

  3. import java.io.InputStreamReader;

  4. import java.util.stream.Collectors;


  5. import org.springframework.core.io.ClassPathResource;


  6. public final class ClassPathResourceReader {

  7.    /**

  8.     * path:文件路径

  9.     * @since JDK 1.8

  10.     */

  11.    private final String path;


  12.    /**

  13.     * content:文件内容

  14.     * @since JDK 1.6

  15.     */

  16.    private String content;


  17.    public ClassPathResourceReader(String path) {

  18.        this.path = path;

  19.    }


  20.    public String getContent() {

  21.        if (content == null) {

  22.            try {

  23.                ClassPathResource resource = new ClassPathResource(path);

  24.                BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));

  25.                content = reader.lines().collect(Collectors.joining("\n"));

  26.                reader.close();

  27.            } catch (IOException ex) {

  28.                throw new RuntimeException(ex);

  29.            }

  30.        }

  31.        return content;

  32.    }

  33. }

使用方式也是相当简单

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

非文本文件读取

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

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


  2. InputStream inputStream = classPathResource.getInputStream();

  3. //生成目标文件

  4. File somethingFile = File.createTempFile("template_export_copy", ".xls");

  5. try {

  6.    FileUtils.copyInputStreamToFile(inputStream, somethingFile);

  7. } finally {

  8.    IOUtils.closeQuietly(inputStream);

  9. }

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

参考文章:

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

 往期推荐:


长按2秒,识别二维码,关注我

原文作者:MavenTalk;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2016-07-13

  • 博文量
    461
  • 访问量
    189201