25--File类和递归

2023-12-20 13:40:53

1、File类

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

1.1 File概述

File类及File相关的的各种流,都定义在java.io包下。

一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。

File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。

  • File对象可以作为参数传递给流的构造器。

想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。

1.2 File类构造方法

方法名

说明

public File(String pathname)

通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。

public File(String parent, String child)

父路径名字符串和子路径名字符串创建新的 File实例。

public File(File parent, String child)

父抽象路径名和子路径名字符串创建新的 File实例。

关于路径:

绝对路径:从盘符开始的路径,这是一个完整的路径。

相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。

  • IDEA中,main中的文件的相对路径,是相对于"当前工程"
  • IDEA中,单元测试方法中的文件的相对路径,是相对于"当前module"

代码演示

package com.suyv.file;

import org.junit.Test;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 13:59
*@Description: File类的构造方法
*/
public class FileDemo01 {

    // public File(String pathname)
    // 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
    @Test
    public void Test01(){
        // 使用相对路径创建File对象
        File file1 = new File("aaa.txt");
        // 获取文件绝对路径
        System.out.println(file1.getAbsoluteFile());    // F:\Java\JavaSE\Day17\aaa.txt

        // 使用绝对路径创建File对象
        File file2 = new File("D:\\aaa.txt");
        // 获取文件绝对路径
        System.out.println(file2.getAbsoluteFile());    // D:\aaa.txt
    }

    // public File(String parent, String child)
    // 从父路径名字符串和子路径名字符串创建新的 File实例。
    @Test
    public void Test02(){

        String parent = "D:\\aaa";

        File file1 = new File(parent,"a1.txt");
        // 获取文件绝对路径
        System.out.println(file1.getAbsoluteFile());    // D:\aaa\a1.txt

    }

    // public File(File parent, String child)
    // 从父抽象路径名和子路径名字符串创建新的 File实例。
    @Test
    public void Test03(){
        // 使用绝对路径创建File对象
        File parent = new File("D:\\aaa");
        File file1 = new File(parent,"a.txt");
        // 获取文件绝对路径
        System.out.println(file1.getAbsoluteFile());    // D:\aaa\a.txt

        // 使用相对路径创建File对象
        File file = new File("aaa");
        File file2 = new File(file,"a.txt");
        // 获取文件绝对路径
        System.out.println(file2.getAbsoluteFile());    // F:\Java\JavaSE\Day17\aaa\a.txt
    }

}

一个File对象代表硬盘中实际存在的一个文件或者目录。

无论该路径下是否存在文件或者目录,都不影响File对象的创建。

1.3 File类的常用方法

1.3.1 获取文件和目录基本信息

public String getName() :获取名称

public String getPath() :获取路径

public String getAbsolutePath():获取绝对路径

public File getAbsoluteFile():获取绝对路径表示的文件

public String getParent():获取上层文件目录路径。若无,返回null

public long length() :获取文件长度(即:字节数)。不能获取目录的长度。

public long lastModified() :获取最后一次的修改时间,毫秒值

package com.suyv.file;

import org.junit.Test;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 14:29
*@Description: 获取文件和目录基本信息
*/
public class FileDemo02 {

    // public String getName() :获取名称
    // public String getPath() :获取路径
    // public String getAbsolutePath():获取绝对路径
    // public File getAbsoluteFile():获取绝对路径表示的文件
    // public String getParent():获取上层文件目录路径。若无,返回null
    // public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
    // public long lastModified() :获取最后一次的修改时间,毫秒值,时间戳

    // 相对路径--文件
    @Test
    public void Test01(){
        // 文件不存在
        File file1 = new File("file/a1.txt");
        System.out.println("文件名称:" + file1.getName());          // 文件名称:a1.txt
        System.out.println("文件路径:" + file1.getPath());          // 文件路径:file\a1.txt
        System.out.println("文件绝对路径:" + file1.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file\a1.txt
        System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\a1.txt
        System.out.println("上层路径:" + file1.getParent());        // 上层路径:file
        System.out.println("文件长度:" + file1.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file1.lastModified());   // 最后修改时间:0

        // 文件存在
        File file2 = new File("file/t1.txt");
        System.out.println("文件名称:" + file2.getName());          // 文件名称:t1.txt
        System.out.println("文件路径:" + file2.getPath());          // 文件路径:file\t1.txt
        System.out.println("文件绝对路径:" + file2.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file\t1.txt
        System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\t1.txt
        System.out.println("上层路径:" + file2.getParent());        // 上层路径:file
        System.out.println("文件长度:" + file2.length());           // 文件长度:20(字节)
        System.out.println("最后修改时间:" + file2.lastModified());   // 最后修改时间:1702967947990(时间戳)
    }

    // 绝对路径--文件
    @Test
    public void Test02(){
        // 文件不存在
        File file1 = new File("F:\\Java\\JavaSE\\Day17\\file\\a1.txt");
        System.out.println("文件名称:" + file1.getName());          // 文件名称:a1.txt
        System.out.println("文件路径:" + file1.getPath());          // 文件路径:F:\Java\JavaSE\Day17\file\a1.txt
        System.out.println("文件绝对路径:" + file1.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file\a1.txt
        System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\a1.txt
        System.out.println("上层路径:" + file1.getParent());        // 上层路径:F:\Java\JavaSE\Day17\file
        System.out.println("文件长度:" + file1.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file1.lastModified());   // 最后修改时间:0

        // 文件存在
        File file2 = new File("F:\\Java\\JavaSE\\Day17\\file\\t1.txt");
        System.out.println("文件名称:" + file2.getName());          // 文件名称:t1.txt
        System.out.println("文件路径:" + file2.getPath());          // 文件路径:F:\Java\JavaSE\Day17\file\t1.txt
        System.out.println("文件绝对路径:" + file2.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file\t1.txt
        System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\t1.txt
        System.out.println("上层路径:" + file2.getParent());        // 上层路径:F:\Java\JavaSE\Day17\file
        System.out.println("文件长度:" + file2.length());           // 文件长度:20(字节)
        System.out.println("最后修改时间:" + file2.lastModified());   // 最后修改时间:1702967947990(时间戳)
    }


    // 相对路径--目录
    @Test
    public void Test03(){
        // 目录不存在
        File file1 = new File("file1");
        System.out.println("文件名称:" + file1.getName());          // 文件名称:file1
        System.out.println("文件路径:" + file1.getPath());          // 文件路径:file1
        System.out.println("文件绝对路径:" + file1.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file1
        System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file1
        System.out.println("上层路径:" + file1.getParent());        // 上层路径:null
        System.out.println("文件长度:" + file1.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file1.lastModified());   // 最后修改时间:0

        // 目录存在
        File file2 = new File("file");
        System.out.println("文件名称:" + file2.getName());          // 文件名称:file
        System.out.println("文件路径:" + file2.getPath());          // 文件路径:file
        System.out.println("文件绝对路径:" + file2.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file
        System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file
        System.out.println("上层路径:" + file2.getParent());        // 上层路径:null
        System.out.println("文件长度:" + file2.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file2.lastModified());   // 最后修改时间:1702967947990(时间戳)
    }

    // 绝对路径--目录
    @Test
    public void Test04(){
        // 目录不存在
        File file1 = new File("F:\\Java\\JavaSE\\Day17\\file1");
        System.out.println("文件名称:" + file1.getName());          // 文件名称:file1
        System.out.println("文件路径:" + file1.getPath());          // 文件路径:F:\Java\JavaSE\Day17\file1
        System.out.println("文件绝对路径:" + file1.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file1
        System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file1
        System.out.println("上层路径:" + file1.getParent());        // 上层路径:F:\Java\JavaSE\Day17
        System.out.println("文件长度:" + file1.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file1.lastModified());   // 最后修改时间:0

        // 目录存在
        File file2 = new File("F:\\Java\\JavaSE\\Day17\\file");
        System.out.println("文件名称:" + file2.getName());          // 文件名称:file
        System.out.println("文件路径:" + file2.getPath());          // 文件路径:F:\Java\JavaSE\Day17\file
        System.out.println("文件绝对路径:" + file2.getAbsolutePath());        // 文件绝对路径:F:\Java\JavaSE\Day17\file
        System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile());   // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file
        System.out.println("上层路径:" + file2.getParent());        // 上层路径:F:\Java\JavaSE\Day17
        System.out.println("文件长度:" + file2.length());           // 文件长度:0
        System.out.println("最后修改时间:" + file2.lastModified());   // 最后修改时间:1702967947990(时间戳)
    }
}

1.3.2 列出目录的下一级

public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

package com.suyv.file;

import org.junit.Test;

import java.io.File;
import java.util.Arrays;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 14:49
*@Description: 列出目录的下一级
*/
public class FileDemo03 {

    // public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
    // public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

    @Test
    public void Test01(){
        File file = new File("file");

        String[] list = file.list();

        System.out.println(Arrays.toString(list));  // [t1.txt]
    }


    @Test
    public void Test02(){
        File file = new File("file");

        File[] files = file.listFiles();

        System.out.println(files);      // [Ljava.io.File;@4ee285c6
    }

}

注意事项

调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。

1.3.3 File类的重命名功能

public boolean renameTo(File dest):把文件重命名为指定的文件路径。

package com.suyv.file;

import org.junit.Test;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 15:47
*@Description: File类的重命名功能
*/
public class FileDemo04 {

    // public boolean renameTo(File dest):把文件重命名为指定的文件路径。
    // 同目录时表示重命名
    @Test
    public void Test01() {
        File file1 = new File("file\\abc.txt");
        File file2 = new File("file\\hello.txt");

        boolean renameSuccess = file1.renameTo(file2);
        System.out.println(renameSuccess ? "重命名成功" : "重命名失败");
    }

    // file1.renameTo(file2):要想此方法执行完,返回true。
    // 要求:file1必须存在,且file2必须不存在,且file2所在的文件目录需要存在。
    // 不同目录时相当于剪切文件
    @Test
    public void Test02(){
        File file1 = new File("file\\abc.txt");
        File file2 = new File("hello.txt");

        boolean renameSuccess = file1.renameTo(file2);
        System.out.println(renameSuccess ? "重命名成功" : "重命名失败");
    }

}

1.3.4 判断功能的方法

public boolean exists() :此File表示的文件或目录是否实际存在。

public boolean isDirectory() :此File表示的是否为目录。

public boolean isFile() :此File表示的是否为文件。

public boolean canRead() :判断是否可读

public boolean canWrite() :判断是否可写

public boolean isHidden() :判断是否隐藏

package com.suyv.file;

import org.junit.Test;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 16:38
*@Description: File类判断功能的方法
*/
public class FileDemo05 {

    // public boolean exists() :此File表示的文件或目录是否实际存在。
    // public boolean isDirectory() :此File表示的是否为目录。
    // public boolean isFile() :此File表示的是否为文件。
    // public boolean canRead() :判断是否可读
    // public boolean canWrite() :判断是否可写
    // public boolean isHidden() :判断是否隐藏

    @Test
    public void Test01(){
        // 文件存在
        File file1 = new File("file\\t1.txt");
        // 文件不存在
        File file2 = new File("file\\t2.txt");
        // 目录存在
        File file3 = new File("file\\test");
        // 目录不存在
        File file4 = new File("file\\test01");
        // 隐藏文件
        File file5 = new File("file\\hidden.txt");

        // exists()
        System.out.println(file1.exists());     // true
        System.out.println(file2.exists());     // false

        // isDirectory() 结果为true的条件是文件夹必须存在,结果为false的当前文件夹不存在或者不是文件夹
        System.out.println(file1.isDirectory());    // false
        System.out.println(file3.isDirectory());    // true

        // isFile   结果为true的条件是文件必须存在,结果为false的当前文件夹不存在或者不是文件
        System.out.println(file1.isFile());     // true
        System.out.println(file3.isFile());     // false

        // canRead()
        System.out.println(file1.canRead());    // true

        // canWrite()
        System.out.println(file1.canWrite());   // true

        // isHidden()
        System.out.println(file1.isHidden());   // false
        System.out.println(file5.isHidden());   // true
        
    }

}

如果文件或目录不存在,那么exists()、isFile()和isDirectory()都是返回false

1.3.5 创建、删除功能

public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false。

public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。

public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。

public boolean delete() :删除文件或者文件夹

删除注意事项:① Java中的删除不走回收站。

② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。

package com.suyv.file;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 16:53
*@Description: 创建、删除功能
*/
public class FileDemo06 {

    // public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false。
    // public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
    // public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。
    // public boolean delete() :删除文件或者文件夹删除注意事项:
    // ① Java中的删除不走回收站。② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。

    // creatNewFile()创建文件时,必须保证该文件的父级目录必须存在
    @Test
    public void Test01() throws IOException {
        File file = new File("file\\红楼梦.txt");
        if (file.createNewFile()) {
            System.out.println("创建文件成功");
        } else {
            System.out.println("创建文件失败");
        }
    }

    // mkdir()创建文件夹时,如果父级目录不存在,则不创建该文件夹
    @Test
    public void Test02(){
        File file = new File("file\\小说");
        if (file.mkdir()) {
            System.out.println("创建成功");
        } else {
            System.out.println("创建失败");
        }
    }

    // mkdirs()创建文件夹时,如果父级目录不存在,则创建父级目录
    @Test
    public void Test03(){
        File file = new File("file\\文学\\历史");
        if (file.mkdirs()) {
            System.out.println("创建成功");
        } else {
            System.out.println("创建失败");
        }
    }

    // delete()如果目录中有内容则不能删除
    @Test
    public void Test04(){
        
        File file = new File("file\\test\\t.txt");
        if (file.delete()) {
            System.out.println("删除成功");
        } else {
            System.out.println("删除失败");
        }

        File file1 = new File("file\\文学");
        if (file1.delete()) {
            System.out.println("删除成功");
        } else {
            System.out.println("删除失败");
        }
    }
}

2、递归

2.1 递归概述

2.1.1 什么是递归

指在当前方法直接或者间接调用自己的情况。

2.1.2 递归的分类

递归分为两种,直接递归 和 间接递归。

直接递归:称为方法自身调用自己。A方法调用B方法B方法调用A方法..

间接递归:可以A方法调用B方法,B方法调用C方法,C方法调用A方法。

2.1.3 递归的注意事项

递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。

在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

构造方法中禁止递归

2.2 递归案例

2.2.1 递归累加求和

需求

  • 计算1 ~ n的和

分析

  • num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。

代码实现

package com.suyv.recursion;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:33
*@Description: 递归累加求和
 */
public class RecursionDemo {
    public static void main(String[] args) {
        System.out.println(getSum(5));
    }

    public static int getSum(int num){

        if (num == 1){
            return 1;
        }

        int ge = getSum(num - 1);
        return ge + num;
    }
}

2.2.2 递归求阶乘

什么是阶乘

  • 所有小于及等于该数的正整数的积。使用递归求5的阶乘5! = 5 * 4 * 3 * 2 * 1 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1求n的阶乘 n * (n - 1)!

求N阶乘公式

  • n! = n * (n-1) ... 3 * 2 * 1

分析

  • 这与累和类似,只不过换成了乘法运算,学员可以自己练习,需要注意阶乘值符合int类型的范围。推理得出:n! = n * (n-1)!

代码实现

package com.suyv.recursion;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:44
*@Description: 递归求阶乘
*/
public class RecursionDemo02 {
    public static void main(String[] args) {
        System.out.println(getSum(5));
    }

    public static int getSum(int num){

        if (num == 1){
            return 1;
        }

        int ge = getSum(num - 1);
        return ge * num;
    }
}

3、综合案例

3.1 打印多级目录

分析

  • 多级目录的打印,就是当目录的嵌套。遍历之前,无从知道到底有多少级目录,所以我们还是要使用递归实现。

代码实现

package com.work;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 18:23
*@Description: 使用递归
*/
public class Demo03 {
    public static void main(String[] args) {
        // 定义一个文件夹,在该文件夹中有三个子文件和两个子文件夹,再每一个子文件夹中又各有几个子文件。
        // 要求: 打印文件夹下的所有的子文件名和文件完整路径(包含子文件下的文件哦!)

        // 创建文件夹对象
        File file = new File("D:\\test");
        String path = file.getPath();
        printFile(path);

    }

    // 使用递归方法
    public static void printFile(String path){
        File file = new File(path);
        // 判断文件是否存在
        if (file.exists()) {
            // 取出文件中的目录和文件
            File[] fileArray = file.listFiles();
            for (File f : fileArray) {
                // 判断是否为目录
                if (f.isDirectory()) {
                    printFile(f.getPath());
                } else {
                    System.out.println(f.getName() + "的绝对路径为:" + f.getAbsolutePath());
                }
            }
        }
    }

}

3.2 文件搜索

需求

  • 搜索D:\aaa 目录中的.java 文件。

需求分析

  • 目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录。遍历目录时,获取的子文件,通过文件名称的后缀,判断是否符合条件。

代码实现

package com.suyv.recursion;

import java.io.File;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:46
*@Description: TODO
*/
public class RecursionDemo03 {
    public static void main(String[] args) {
        // 创建File对象
        File dir  = new File("D:\\aaa");
        // 调用打印目录方法
        printDir(dir);
    }

    public static void printDir(File dir) {
        // 获取子文件和目录
        File[] files = dir.listFiles();

        // 循环打印
        for (File file : files) {
            if (file.isFile()) {
                // 是文件,判断文件名并输出文件绝对路径
                if (file.getName().endsWith(".java")) {
                    System.out.println("文件名:" + file.getAbsolutePath());
                }
            } else {
                // 是目录,继续遍历,形成递归
                printDir(file);
            }
        }
    }
}

文章来源:https://blog.csdn.net/weixin_46612641/article/details/135105039
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。