techiall / Blog

🍋 [My Blog] See discussions
https://github.com/techiall/Blog/discussions
MIT License
8 stars 1 forks source link

Spring Boot 读取 resources 目录下文件 #59

Open techiall opened 4 years ago

techiall commented 4 years ago

回头看了一下之前写的这篇文章,感觉很多不足之处

最近又遇到一样的需求,趁次机会,重新编写该文章。

resources 文件夹内容如下,假如要读取 user.txt 里面的文本,并按行输出。

├── resources
│   ├── application.yml
│   ├── data
│   │   └── user.txt
│   └── exception.json

user.txt 内容为。

admin   admin
root    root

可以使用 org.springframework.core.io.ClassPathResource 并配合 FileCopyUtils,demo 如下:

import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

    public void run() throws IOException {
        byte[] bytes = read("data/user.txt");
        List<String> list = Arrays.stream(new String(bytes).split("\n"))
                .collect(Collectors.toList());
        list.forEach(System.out::println);
    }

    private static byte[] read(String path) throws IOException {
        ClassPathResource resource = new ClassPathResource(path);
        return FileCopyUtils.copyToByteArray(resource.getInputStream());
    }

输出结果为:

admin   admin
root    root

当然了你也可以读取 resource 里面的其他文件,如 application.yml,一样是可以读取成功的。

other

很多人在开发的时候可以正常读取 resource 文件夹里面的文件,但是打包发布到线上,就报错。

很大原因是使用了诸如 File / Files / Paths 之类的方法。

(毕竟 ClassPathResource 里面有 getURI() / getPath() / getFile(),然后再去读取,然后你会发现这么读取都是失败的。

techiall commented 4 years ago

返回 iterator

    @SneakyThrows
    public static <T> Iterator<T> read(String resourceLocation, Function<String, T> mapper) {
        ClassPathResource classPathResource = new ClassPathResource(resourceLocation);
        byte[] read = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());

        return Arrays.stream(new String(read).split("\n")).map(mapper).iterator();
    }
techiall commented 4 years ago
public class ResourceUtils {

    private ResourceUtils() {
        throw new IllegalStateException("Utility class");
    }

    @SneakyThrows
    public static <T> List<T> fileRead(String resourceLocation, Function<String, T> mapper) {
        if (resourceLocation == null) {
            return Collections.emptyList();
        }

        if (-1 != resourceLocation.compareToIgnoreCase("classpath:")) {
            resourceLocation = resourceLocation.replaceAll("(?i)classpath:", "");
        }

        ClassPathResource classPathResource = new ClassPathResource(resourceLocation);
        byte[] read = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());

        return Arrays.stream(new String(read).split("\n"))
                .map(mapper).collect(Collectors.toList());
    }