对于一个嵌套的目录,获取目录下所有的文件,可以使用以下两种方式:


1. 通过递归获取


File类提供了如下两个方法:


file.list():返回目录下文件和子目录名;(不会递归)

file.listFiles():返回目录下文件和子目录File对象;(不会递归)

/**

     * 得到文件名称

     *

     * @param path 路径

     * @return {@link List}<{@link String}>

     */

    private List<String> getFileNames(String path) {

        File file = new File(path);

        if (!file.exists()) {

            return null;

        }

        List<String> fileNames = new ArrayList<>();

        return getFileNames(file, fileNames);

    }


/**

     * 得到文件名称

     *

     * @param file      文件

     * @param fileNames 文件名

     * @return {@link List}<{@link String}>

     */

    private List<String> getFileNames(File file, List<String> fileNames) {

        File[] files = file.listFiles();

        for (File f : files) {

            if (f.isDirectory()) {

                getFileNames(f, fileNames);

            } else {

                fileNames.add(f.getName());

            }

        }

        return fileNames;

    }

例子中List只是存放了文件夹下所有的文件名,可以根据需求修改List中存放的元素属性。比如可以直接将File对象存入。


2. 使用Files.walk()方法

在jdk8中,可以使用walk方法递归的去查找目录下所有文件。


// 路径

        String path = "D:\\xxx";

try (Stream<Path> paths = Files.walk(Paths.get(path))){

            List<Path> fileNames = paths

                    .filter(Files::isRegularFile)

                    .collect(Collectors.toList());

        } catch (IOException e) {

            e.printStackTrace();

        }

walk方法会自动递归子目录。

上例使用了Try with Resources模式,它可以确保无论在什么情况下,流都将关闭。

解释:

如果try块和finally块中的方法都抛出异常那么try块中的异常会被抑制(suppress),只会抛出finally中的异常,而把try块的异常完全忽略。而try-with-resources语句能够帮你自动调用资源的close()函数关闭资源不用到finally块。


walk方法解释:


通过遍历以给定起始文件为根的文件树,返回一个用 Path 惰性填充的 Stream。文件树是深度优先遍历的,流中的元素是 Path 对象,就好像通过解析相对路径来获得的一样。此方法的工作方式就像调用它等同于评估表达式: walk(start, Integer.MAX_VALUE, options) 换句话说,它访问文件树的所有级别。返回的流封装了一个或多个 DirectoryStream。如果需要及时处理文件系统资源,则应使用 try-with-resources 构造来确保在流操作完成后调用流的 close 方法。对关闭的流进行操作将导致 illegalStateException。


illegalStateException是无效状态异常。表示当前对客户端的响应已经结束,不能在响应已经结束(或说消亡)后再向客户端(实际上是缓冲区)输出任何内容。

一般来说无效状态异常是因为弄错了调用一个方法的流程,

例如:比如在JSP/Servlet编程中,服务器已经开始把数据发客户端了,却想改动字符集encoding参数,这个就是错误,因为开始复数据到客户端后就不能再修改任何Http header内容,它们已经发出去了,无法再修改了。


maxDepth参数,设置要递归的深度;Files.walk(Paths.get(path),2)

默认不会自动跟随符号链接, 设置options参数FOLLOW_LINKS选项,则遵循符号链接。 Files.walk(Paths.get(path),FileVisitOption.FOLLOW_LINKS)


示例:


String path = "D:\\xxx";

//过滤出目录

try (Stream<Path> paths = Files.walk(Paths.get(dirName))) {

    paths.filter(Files::isDirectory)

            .forEach(System.out::println);

}

 

//按后缀名过滤

try (Stream<Path> paths = Files.walk(Paths.get(dirName), 2)) {

    paths.map(path -> path.toString()).filter(f -> f.endsWith(".png"))

            .forEach(System.out::println);

}

需求:传进来上传的文件名通过","分割,检查文件夹中是否存在,不存在返回缺失的文件名

代码:


/**

     * 校验文件

     *

     * @param data  文件名数据

     * @return {@link String}

     */

    @Override

    public String validationFile(String data) {

        List<String> fileNames = new ArrayList<>();

        try (Stream<Path> paths = Files.walk(Paths.get(path))) {

            fileNames = paths

                    .filter(Files::isRegularFile)

                    .map(file -> file.getFileName().toString())

                    .collect(Collectors.toList());

        } catch (IOException e) {

            e.printStackTrace();

        }

        //传进来的files

        String[] fileNameArr = data.split(",");

        List<String> missingFile = new ArrayList<>();

        for (String s : fileNameArr) {

            if (!fileNames.contains(s)) {

                missingFile.add(s);

            }

        }

        if (missingFile.size() == 0) {

            return "1";

        }

        return String.join(",", missingFile);

    }

————————————————

版权声明:本文为CSDN博主「没有翅膀却想飞向天空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_46258463/article/details/126719629