File遍历,递归

1.3 创建和删除方法

刚才有同学问老师,我们不能不用Java代码创建一个文件或者文件夹呀?答案是有的,不光可以创建还可以删除。

**注意:**delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站。

java 复制代码
/**
 * 目标:掌握File创建和删除文件相关的方法。
 */
public class FileTest3 {
    public static void main(String[] args) throws Exception {
        // 创建一个新文件(文件内容为空),创建成功返回true,反之。
        File f1 = new File("D:\\resource\\abcd.txt");
        System.out.println(f1.createNewFile());

        // 用于创建文件夹,注意:只能创建一级文件夹
        File f2 = new File("D:\\resource\\aaa");
        System.out.println(f2.mkdir());

        // 用于创建文件夹,注意:可以创建多级文件夹
        File f3 = new File("D:\\resource\\bbb\\ccc\\ddd");
        System.out.println(f3.mkdirs());

        System.out.println("-------------");

        // 删除文件,或者空文件,注意:不能删除非空文件夹。
        System.out.println(f1.delete());
        System.out.println(f2.delete());
        File f4 = new File("D:\\resource\\");
        System.out.println(f4.delete());
    }
}
java 复制代码
需要注意的是:

```java
1.mkdir(): 只能创建单级文件夹
2.mkdirs(): 才能创建多级文件夹
3.delete(): 文件可以直接删除,但是文件夹只能删除空的文件夹,文件夹有内容删除不了。
```

```java
1. 创建多级目录使用哪个方法?
	public boolean mkdirs()
2. 删除文件需要注意什么?
	可以删除文件、空文件夹。
	默认不能删除非空文件夹。
```

1.4 遍历文件夹方法

有人说,想获取到一个文件夹中的内容,有没有方法呀?也是有的,下面我们就学习两个这样的方法。

java 复制代码
/**
 * 目标:掌握File提供的遍历文件夹的方法。
 */
public class FileTest4 {
    public static void main(String[] args) throws Exception {
        // 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回
        File f1 = new File("E:\\胜雅教育\\Java课程\\01.JavaSE\\基础阶段");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }

        System.out.println("----------------------------------");

        File[] files = f1.listFiles();
        for (File file : files) {
            // 获取文件的绝对路径
            System.out.println(file.getAbsolutePath());
        }

        System.out.println("----------------------------------");

        File f = new File("D:\\resource\\aaa");
        File[] files1 = f.listFiles();
        System.out.println(Arrays.toString(files1));
    }
}

这里需要注意几个问题

复制代码
1. 当主调是文件,或者路径不存在时,返回null
2. 当主调是空文件夹时,返回一个长度为0的数组
3. 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
4. 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
5. 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null
复制代码
如何遍历文件夹下的文件对象,使用哪个API,有什么特点?
    public File[] listFiles()(常用)。
    只能遍历当前文件夹对象下的一级文件对象。

关于遍历文件夹的基本操作就学习完了。 但是有同学如果想要获取文件夹中子文件夹的内容,那目前还做不到。但是学习下面的递归知识就很容易做到了。

二、递归

各位同学,为了获取文件夹中子文件夹的内容,我们就需要学习递归这个知识点。但是递归是什么意思,我们需要单独讲一下。学习完递归是什么,以及递归的执行流程之后,我们再回过头来用递归来找文件夹中子文件夹的内容。

2.1 递归算法引入

  • 什么是递归?

    递归是一种算法,在程序设计语言中广泛应用。

    从形式上说:方法调用自身的形式称为方法递归( recursion)。

  • 递归的形式:

    直接递归:方法自己调用自己。

    间接递归:方法调用其他方法,其他方法又回调方法自己。

使用方法递归时需要注意的问题:

递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。

如下面的代码。

java 复制代码
/**
 * 目标:认识一下递归的形式。
 */
public class RecursionTest1 {
    public static void main(String[] args) {
        test1();
    }

    // 直接方法递归
    private static void test1() {
        System.out.println("---------test1---------");
        test1(); // 直接递归:方法自己调用自己。
    }

    // 间接方法递归 (开发中很少使用)
    public static void test2(){
        System.out.println("---test2---");
        test3();
    }

    public static void test3(){
        test2(); // 间接递归
    }

如果直接执行上面的代码,会进入死循环,最终导致栈内存溢出

2.2 递归算法的执行流程

为了弄清楚递归的执行流程,接下来我们通过一个案例来学习一下。

案例需求:计算n的阶乘,比如5的阶乘 = 1 * 2 * 3 * 4 * 5 ; 6 的阶乘 = 1 * 2 * 3 * 4 * 5 * 6

分析需求用递归该怎么做

n的阶乘: 公式计算: 1*2*3*..*(n-1)*n 等价与 f(n) = f(n-1)*n

假设f(n)表示n的阶乘,那么我们可以推导出下面的式子

f(5) = 5*4*3*2*1

f(5) = f(4)*5

f(4) = f(3)*4

f(3) = f(2)*3

f(2) = f(1)*2

f(1) = 1

总结规律:

除了f(1) = 1; 出口

其他的f(n) = f(n-1)*n

我们可以把f(n)当做一个方法,那么方法的写法如下

java 复制代码
/**
 * 目标:掌握递归的应用,执行流程和算法思想。
 */
public class RecursionTest2 {
    public static void main(String[] args) {
        int result = f(5);
        System.out.println("5的阶乘是:" + result);
    }

    //求n个数的阶乘
    public static int f(int n){
        // 终结点
        if(n == 1){
            return 1;
        }else {
            return f(n - 1) * n;
        }
    }
}

2.3 递归文件搜索

学习完递归算法执行流程后,最后我们回过头来。再来看一下,如果使用递归来遍历文件夹。

案例需求:在D:\\判断下搜索TIM.exe这个文件,然后直接输出。 绝对路径

分析:

1.先调用文件夹的listFiles方法,获取文件夹的一级内容,得到一个数组

2.然后再遍历数组,获取数组中的File对象(文件/文件夹)

3.因为File对象可能是文件也可能是文件夹,所以接下来就需要判断

判断File对象如果是文件,就获取文件名,如果文件名是`TIM.exe`则打印,否则不打印

判断File对象如果是文件夹,就递归执行1,2,3步骤

所以:把1,2,3步骤写成方法,递归调用即可。

java 复制代码
/**
 * 目标:掌握文件搜索的实现。
 */
public class RecursionTest3 {
    public static void main(String[] args) throws Exception {
        searchFile(new File("D:/") , "TIM.exe");
    }

    /**
     * 去目录下搜索某个文件
     * @param dir 目录
     * @param fileName 要搜索的文件名称
     */
    private static void searchFile(File dir, String fileName) throws Exception {
        // 1. 把非法的情况都拦截住
        if (dir == null || !dir.exists() || dir.isFile()){
            return; // 代表无法搜索
        }
        /**
         * 2. dir不是null, 存在, 一定是目录对象
         * 获取当前目录下的全部一级文件对象
         */
        File[] files = dir.listFiles();

        // 3. 判断当前目录下是否存在一级文件对象, 以及是否存在可以拿到一级文件对象
        if (files != null && files.length > 0){
            // 4. 遍历全部一级文件对象
            for (File file : files) {
                // 5. 判断当前file是文件, 还是文件夹
                if (file.isFile()){ // 是文件
                    // 是文件, 判断这个文件名是否是我们要找的文件名
                    if (file.getName().contains(fileName)){
                        // 找到了  打印当前文件的绝对路径
                        System.out.println("找到了: " + file.getAbsolutePath());
                        // 运行当前文件
                        Runtime runtime = Runtime.getRuntime();
                        runtime.exec(file.getAbsolutePath()); // 执行方法
                    }
                }else {
                    // 是文件夹, 继续重复这个过程(递归继续找)
                    searchFile(file, fileName);
                }
            }
        }
    }
}
相关推荐
Rain的Java大神之路2 分钟前
别再死磕 MySQL 了:向量数据库与 RAG 生产落地实录(Java 工程师专场)
java·后端·面试
七夜zippoe3 分钟前
Spring AI 是什么?Java 工程师的 AI 开发第一站
java·人工智能·spring·ai·开发
是真的小外套13 分钟前
2023年软考中级信息安全工程师|选择题考点+5道案例分析真题解析(含答案)
java·服务器·网络
会编程的吕洞宾33 分钟前
Spring AI 2.0 结构化输出实战:让大模型返回精准 JSON 不再“抽风“,准确率从 78% 拉到 99%
java·后端
项目題供诗36 分钟前
ai大模型(三)
java
weixin_307779131 小时前
C++代码实现MATLAB中的spectralcluster函数功能
开发语言·c++·算法·matlab
鸽鸽程序猿1 小时前
【项目】【在线判题系统】c端:竞赛报名
c语言·开发语言
wangjialelele1 小时前
一文梳理 Spring Cloud 核心组件:Eureka、Nacos、OpenFeign、LoadBalancer 与 Gateway
java·spring boot·spring·spring cloud·微服务·nacos
用户6222884048191 小时前
站在JDK的角度理解线程池:从execute 到 getTask 一篇讲透
java·面试
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 个人资料管理的需求分析与接口设计
java·开发语言·交友