java Files类 查看文件夹 删除不为空的文件夹

本文介绍了如何使用Java的Files类的walkFileTree方法代替递归方式,更优雅地遍历和操作文件夹。通过创建SimpleFileVisitor实现文件和文件夹的访问,包括预访问目录、访问文件、访问失败和访问后操作。同时展示了如何利用该方法删除文件夹,整个过程清晰易懂,避免了递归的复杂性。
摘要由CSDN通过智能技术生成

在很多时候都会遇到删除一个不为空的文件夹的情景,在不使用Files类时,可以使用递归的方式来删除,但递归的代码不是很容易理解,看起来也不够优雅。于是用Files这个类来操作,代码就变得优雅起来了。

先上一段传统的代码来遍历一个不为空的文件夹,因为用代码来操作文件是十分危险的一个操作,删除文件很有可能就无法恢复,所以先来遍历一下。

FileOperation.java

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

public class FileOperation {
    public static void main(String[] args) throws IOException {
        m1();//传统递归遍历
    }
    private static void m1() {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        printFileAndDir(new File("C:\\Program Files\\Java\\jdk1.8.0_131"),dirCount,fileCount);
        System.out.println(dirCount.get());
        System.out.println(fileCount.get());
    }

    private static void printFileAndDir(File root, AtomicInteger dirCount, AtomicInteger fileCount){
        for (File file : root.listFiles()) {
            if (file.isDirectory()){
                dirCount.incrementAndGet();
                System.out.println("====>" + file);
                printFileAndDir(file,dirCount,fileCount);
            }else {
                fileCount.incrementAndGet();
                System.out.println("---->" + file);
            }
        }
    }
}

代码中的AtomicInteger可以看做成一个计数器,这里不使用简单的int count作为计数器的原因是,在后续代码中的操作是会在一个内部类中的,所以int count这样的计数器则无效,AtomicInteger对象的incrementAndGet()方法可以理解为计数器+1。(这里不用太过计较这个类)

这样的递归代码可能不是很容易理解的,下面就放上Files类操作的代码

TestFilesWalkFileTree .java

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

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        m1();//遍历目录下的文件和文件夹
    }
    private static void m1() throws IOException {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_131"),new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("======>" + dir);
                dirCount.incrementAndGet();
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println("----->" + file);
                fileCount.incrementAndGet();
                return super.visitFile(file, attrs);
            }
        });
        System.out.println(dirCount.get());
        System.out.println(fileCount.get());
    }
}

解释一下这块代码块:

Files.walkFileTree(
Paths.get("C:\\Program Files\\Java\\jdk1.8.0_131"),
new SimpleFileVisitor<Path>(){}
);

这个 Files.walkFileTree(Path start, FileVisitor<? super Path> visitor);静态方法的参数传递两个。
一个是Path类,用于指向要被操作的文件夹,
另一个是一个FileVisitor,此处是一个观察者模式的设计,
new SimpleFileVisitor<Path>(){},这样弄一个内部类就行,重写这个内部类的一些方法,来操作文件夹。
在这里插入图片描述
重写这四个方法即可,不一定要全部重写

  1. preVisitDirectory:访问文件夹之前的操作
  2. visitFile:访问文件时,对文件的操作
  3. visitFileFailed:访问文件失败时,进行一些处理
  4. postVisitDirectory:访问完文件夹之后的操作

有一点要强调的就是,重写这些方法时不要对return进行修改,否则文件夹无法遍历下去

用Files.walkFileTree这个方法来遍历文件夹下的文件夹和文件,这样的代码看过去更容易理解,也更加优雅。

最后附上删除文件夹的代码(也称之为删库跑路代码,hhh)

TestFilesWalkFileTree .java

package com.sixteen.netty;

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

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        m4();//删除文件夹
    }
    private static void m4() throws IOException {
        Files.walkFileTree(Paths.get("E:\\html5 - 副本"),new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("===> 进入" + dir);
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file);
                Files.delete(file);
                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                System.out.println("<=== 退出" + dir);
                Files.delete(dir);
                return super.postVisitDirectory(dir, exc);
            }
        });
    }
}

解释一下删除文件夹的代码,分为以下几个步骤:

  1. 先判断本身一个文件夹还是文件,如果是文件夹,则先进入preVisitDirectory方法,此处无需对文件夹做出什么操作,可以打印一下信息
  2. 当判断为是文件时,进入visitFile方法,此时就可以直接对文件进行操作,此处是删除文件
  3. 当把一个文件夹内的文件都访问过后,要退出这个文件夹时,进入postVisitDirectory方法,由于是文件时会被第2步操作删除文件夹,所以此时的文件夹为空,可以直接删除,这样就把一个文件夹给删除了

如果文件夹内含文件和文件夹,文件夹中的文件夹会重复1~3的步骤,也就是递归,只不过这样写出的代码更加优雅更加容易理解(当然是对比递归而言)。

以上就是Files类walkFileTree方法的一些解释,如有错误,还望大佬们指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值