Spring Boot读取resources目录下的文本文件

Java 8

Spring Boot 2.7.3

IntelliJ IDEA 2022.3.2 (Community Edition)

--

 

开门见山

使用  ClassLoader 的 getResourceAsStream 读取。

注,还可以使用 其下的 静态方法 getSystemResourceAsStream 读取。

函数源码:

ClassLoader部分源码
 public abstract class ClassLoader {
    
    /**
     * Returns an input stream for reading the specified resource.
     *
     * <p> The search order is described in the documentation for {@link
     * #getResource(String)}.  </p>
     *
     * @param  name
     *         The resource name
     *
     * @return  An input stream for reading the resource, or <tt>null</tt>
     *          if the resource could not be found
     *
     * @since  1.1
     */
    public InputStream getResourceAsStream(String name) {
        URL url = getResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Open for reading, a resource of the specified name from the search path
     * used to load classes.  This method locates the resource through the
     * system class loader (see {@link #getSystemClassLoader()}).
     *
     * @param  name
     *         The resource name
     *
     * @return  An input stream for reading the resource, or <tt>null</tt>
     *          if the resource could not be found
     *
     * @since  1.1
     */
    public static InputStream getSystemResourceAsStream(String name) {
        URL url = getSystemResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }

}

  ben发布于博客园

测试项目

名称:bootweb

测试文件 为项目 src/main/resources/txtFiles 目录中 的 txtFile001.txt。

内容:仅 5行。文本文件,UTF-8编码

  ben发布于博客园

测试代码

package com.lib.bootweb.runner;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * 读取文件测试
 */
@Component
@Slf4j
public class ReadFileTest implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 输出项目的 classpath
        URL url1 = this.getClass().getClassLoader().getResource("");
        log.info("URL url1={}", url1);
        URL url2 = this.getClass().getClassLoader().getResource("/");
        log.info("URL url2={}", url2);

        this.readTxtFileInResources("txtfiles/txtFile001.txt");

        log.info("ReadFileTest END.");
    }

    /**
     * 读取 src/main/resources 下的 文本文件
     * @param relPath 文本文件相对于 src/main/resources 的 相对路径
     */
    private void readTxtFileInResources(String relPath) {
        StringBuffer sb = new StringBuffer();

        try (InputStream fileIs = this.getClass().getClassLoader().getResourceAsStream(relPath)) {
            final int maxSize = 1024;
            byte[] buff = new byte[maxSize];
            int read = 0;

            while ((read = fileIs.read(buff, 0, maxSize)) > 0) {
                sb.append(new String(buff, 0, read));
            }
        } catch (IOException e) {
            log.error("发生异常:e=", e);
            throw new RuntimeException(e);
        }

        log.info("StringBuffer sb=\r\n{}", sb);
    }
}

 

疑问,如果缓存的长度不是 1024字节,该怎么处理?如果文件不是UTF-8编码,该怎么处理?TODO ben发布于博客园

解释(参考资料#4):

 

测试方式:

运行bootweb项目,检查输出日志。

注意输出的 url1、url2 的信息。 ben发布于博客园

 

在IDEA中运行

运行结果:

URL url1=file:/D:/bootweb/target/classes/
URL url2=null
StringBuffer sb=
123456789
abcdefgHIJKLMN
   232   @#$$@_+=
第4行

ReadFileTest END.

成功输出了文件内容。

 

运行时,文件是从 classes 中获取的:

  ben发布于博客园

使用java -jar命令运行

打包(忽略 test):

打包后生成:bootweb-0.0.1-SNAPSHOT.jar

  ben发布于博客园

使用 IDEA的终端 运行:乱码问题

进入IDEA的终端,执行:

java -jar .\target\bootweb-0.0.1-SNAPSHOT.jar

 运行结果:

URL url1=jar:file:/D:/bootweb/target/bootweb-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!
/
URL url2=jar:file:/D:/bootweb/target/bootweb-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!
/
StringBuffer sb=
123456789
abcdefgHIJKLMN
   232   @#$$@_+=
绗?4琛?

ReadFileTest END.

运行正常。

但是,存在乱码——原因:终端的 字符集不是UTF-8。 ben发布于博客园

 

使用 参考资料#3 方式修改终端的编码,再 添加 -Dfile.encoding=UTF-8 执行,但是还是乱码。

 

使用Windows 本身的终端运行:正常

打开终端,执行 chcp 65001;

再执行:java -jar -Dfile.encoding=UTF-8 target\bootweb-0.0.1-SNAPSHOT.jar

执行结果:无乱码

 

--END--

 

本文链接:

 https://www.cnblogs.com/luo630/p/17073436.html

 

参考资料

1、Java file.encoding 

https://www.cnblogs.com/virgosnail/p/10868402.html

2、java 读取classpath下的文件

https://blog.csdn.net/leveretz/article/details/127984226

3、修改win10终端控制台默认编码为utf-8

https://blog.csdn.net/weixin_45265547/article/details/121931397

在窗口中输入chcp 65001

4、IO流 FileInputStream与FileReader

https://blog.csdn.net/weixin_45073048/article/details/102574013

5、

 

 

 ben发布于博客园

posted @ 2023-01-29 21:12  快乐的欧阳天美1114  阅读(2195)  评论(0编辑  收藏  举报