NIO中Files的WalkFileTreeAPI方法

功能

用于快速便捷的遍历目录和文件

实现

采用了二十三种设计模式中的访问者模式

方法参数

static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
走一个文件树。
static Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor)
走一个文件树。 

遍历行为控制器FileVisitor

接口java.nio.file.FileVisitor包含四个方法,涉及到遍历过程中的几个重要的步骤节点。一般实际中使用SimpleFileVisitor简化操作。

  • preVisitDirectory 访问一个目录,在进入之前调用。
  • postVisitDirectory 一个目录的所有节点都被访问后调用。遍历时跳过同级目录或有错误发生,Exception会传递给这个方法
  • visitFile 文件被访问时被调用。该文件的文件属性被传递给这个方法
  • visitFileFailed 当文件不能被访问时,此方法被调用。Exception被传递给这个方法。

遍历行为结果 FileVisitResult

  • CONTINUE 继续遍历
  • SKIP_SIBLINGS 继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
  • SKIP_SUBTREE 继续遍历,但是忽略子目录,但是子文件还是会访问
  • TERMINATE 终止遍历

示例代码

复制代码
package t2022.t5.t27.nio;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author 14715
 * @Date 2022/5/30 16:15
 * @Version 1.0
 *
 * 遍历文件或者目录的API
 */
public class WalkFileTree {
    public static void main(String[] args) {
//        visitJarFile();
//        visitDirAndFile();
//        deleteMultiAspectFile();
//        fileCopy();
    }

    private static void fileCopy() {
        String source = "E:\\xmanager5";
        String target = "E:\\xmanager5LZP";
        try {
            Files.walk(Paths.get(source)).forEach(path -> {
                try {
                    // 判断当前path是目录还是文件
                    /*
                        1、若为目录,则创建出目录
                        2、若为文件,则直接将文件从原目录拷贝到目标目录即可
                     */
                    String targetName = path.toString().replace(source, target);
                    if (Files.isDirectory(path)) {
                        Files.createDirectory(Paths.get(targetName));
                    } else if (Files.isRegularFile(path)) {
                        Files.copy(Paths.get(path.toString()), Paths.get(targetName));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除多级目录下的文件
     * 注意:该方法不走回收站,使用需谨慎
     */
    private static void deleteMultiAspectFile() {
        try {
            Files.walkFileTree(Paths.get("E:\\alipay.trade.page.pay-JAVA-UTF-8.zip"), new SimpleFileVisitor<Path>(){
                /**
                 * 遍历文件
                 * 每遍历到一个文件,就将该文件删除
                 * @param file
                 * @param attrs
                 * @return
                 * @throws IOException
                 */
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return super.visitFile(file, attrs);
                }

                /**
                 * 当访问完当前目录并跳出该目录时调用该方法
                 * 跳出时,当前目录已经为空,则直接删除空目录即可
                 * @param dir
                 * @param exc
                 * @return
                 * @throws IOException
                 */
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return super.postVisitDirectory(dir, exc);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void visitJarFile() {
        AtomicInteger jarCnt = new AtomicInteger();
        try {
            Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_121"), new SimpleFileVisitor<Path>(){
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    if (file.toString().endsWith(".jar")) {
                        System.out.println(file);
                        jarCnt.incrementAndGet();
                    }
                    return super.visitFile(file, attrs);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("jar cnt:" + jarCnt);
    }

    private static void visitDirAndFile() {
        AtomicInteger dirCnt = new AtomicInteger();
        AtomicInteger fileCnt = new AtomicInteger();
        try {
            Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_121"), new SimpleFileVisitor<Path>(){
                /**
                 * 访问目录
                 * @param dir
                 * @param attrs
                 * @return
                 * @throws IOException
                 */
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    System.out.println("====>" + dir);
                    dirCnt.incrementAndGet();
                    return super.preVisitDirectory(dir, attrs);
                }

                /**
                 * 访问文件
                 * @param file
                 * @param attrs
                 * @return
                 * @throws IOException
                 */
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    System.out.println(file);
                    fileCnt.incrementAndGet();
                    return super.visitFile(file, attrs);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("dir cnt:" + dirCnt);
        System.out.println("file cnt:" + fileCnt);
    }
}
复制代码

测试效果

遍历目录和文件

遍历jar文件

 

posted @   没有你哪有我  阅读(315)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
历史上的今天:
2021-05-30 如何在cmd命令行窗口测试MySQL数据的innodb存储引擎行锁实现方式
2021-05-30 LeetCode第243场周赛第三题——5774. 使用服务器处理任务(优先队列)
2021-05-30 计算机当中为啥将-128的补码定义为【10000000】
2021-05-30 判断一个数是否为2的幂次方
点击右上角即可分享
微信分享提示