File类和递归

第一章 File类

1.1 概述

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

java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作

我们可以使用File的方法

​ 创建一个文件/文件夹

​ 删除文件/文件夹

​ 获取文件/文件夹

​ 判断文件/文件夹是否存在

​ 对文件夹进行遍历

​ 获取文件的大小

File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法

重点:记住这三个单词

​ file:文件

​ directory:文件夹/目录

​ path:路径

/**
 * static String pathSeparator
 *           与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
 * static char pathSeparatorChar
 *           与系统有关的路径分隔符。
 * static String separator
 *           与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
 * static char separatorChar
 *           与系统有关的默认名称分隔符。
 *
 *
 *           操作路径不能写死了
 *           "D:+"File.separator"+Learn+"File.separator"+javaAgain"
*/
public class Demo01File {
    public static void main(String[] args) {
        String pathSeparator = File.pathSeparator;
        //;
        System.out.println(pathSeparator);

        String separator = File.separator;
        // \
        System.out.println(separator);

    }
}

绝对路径

是一个完整的路径,以盘符(C:,D:)开始的路径:D:\Learn\javaAgain\123.txt

相对路径

是一个简化的路径,相对路径指的是相对于当前项目的根目录

如果使用当前项目的根目录,路径可以简化书写

D:\Learn\javaAgain\123.txt —>简化为:123.txt(可以省略项目的根目录)

注意:

1、路径是不区分大小写的

2、路径中的文件名称分隔符Windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

1.2 构造方法

· public File(String pathname):通过将给定路径名字字符转换为抽象路径名来创建一个新File实例

· public File(String parent,String child):根据parent路径名字符串和child路径名字符串创建一个新的File实例

· public File(File parent,String child):根据parent路径名字符串和child路径名字符串创建一个新的File实例

代码演示:

public class Demo02File {
    public static void main(String[] args) {
        /**
         * File类的构造方法
         */
        show03();
    }
/**
 * ·   public File(File  parent,String  child):
 * 根据parent路径名字符串和child路径名字符串创建一个新的File实例
 * 参数:把路径分成了两部分
 * File    parent:父路径
 * String  child:子路径
 *
 * 好处:
 * 父路径和子路径可以单独书写,使用起来非常灵活;父路径和子路径都可以变化
 * 父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象
 *
*/
    private static void show03() {
        File parent = new File("c:\\");
        File file = new File(parent,"hello.java");
        System.out.println(file);
    }

    /**
 * ·   public File(String    parent,String  child):
 * 根据parent路径名字符串和child路径名字符串创建一个新的File实例
 * 参数:把路径分成了两部分
 * String  parent:父路径
 * String  child:子路径
 *
 * 好处:
 *  父路径和子路径可以单独书写,使用起来非常灵活;父路径和子路径都可以变化
*/
    private static void show02(String parent,String child) {
        File file = new File(parent,child);
        System.out.println(file);
    }

    /**
 * ·   public File(String    pathname):
 * 通过将给定路径名字字符转换为抽象路径名来创建一个新File实例
 * 参数:
 *  String pathname:字符串的路径名称
 *  路径可以是文件结尾,也可以是文件夹结尾
 *  路径可以是相对路经,也可以是绝对路径 
 *  创建File类对象,只是把字符串路径封装为File对象,不考虑路径的真假情况
*/
    private static void show01() {
        File f1 = new File("D:\\Learn\\javaAgain+\\123.txt");
        //重写了Object类的toString方法 D:\Learn\javaAgain\123.txt
        System.out.println(f1);

        File f2 = new File("D:\\Learn\\javaAgain");
        System.out.println(f2);

        File f3 = new File("b.txt");
        System.out.println(f3);
    }
}

1.3 常用方法

获取功能的方法

· public String getAbsolutePath():返回此File的绝对路径名字符串

获取的是构造方法中传递的路径

无论路径是绝对的还是相对的,getAbsolutePath()方法返回的都是绝对路径

· public String getPath():将此File转换为路径名字符串

获取构造方法中传递的路径

toString方法调用的就是getPath方法

· public String getName():返回由此File表示的文件或目录的名称

获取的就是构造方法传递路径的结尾部分(文件/文件夹)

· public long length():返回由此File表示的文件的长度

获取的是构造方法指定的文件的大小,以字节为单位

注意:

1、文件夹是没有大小概念的,不能获取文件夹的大小

2、如果构造方法中给出的路径不存在,那么length方法返回0

代码演示如下:

public class Demo03File {
    public static void main(String[] args) {
       show04();

    }

    private static void show04() {
        File  f1 = new File("D:\\Program Files\\java笔记\\Java自我小结\\linux\\2.PNG");
        long length = f1.length();
        System.out.println(length);
    }

    private static void show03() {
        File f1 = new File("D:\\Learn\\javaAgain\\123.txt");
        String name1 = f1.getName();
        System.out.println(name1);
    }

    private static void show02() {
        File f1 = new File("D:\\Learn\\javaAgain\\123.txt");
        File f2 = new File("123.txt");
        String path1 = f1.getPath();
        System.out.println(path1);
        String path2 = f2.getPath();
        System.out.println(path2);

    }

    private static void show01() {
        File f1 = new File("D:\\Learn\\javaAgain\\123.txt");
        String absolutePath1 = f1.getAbsolutePath();
        System.out.println(absolutePath1);

        File f2 = new File("123.txt");
        String absolutePath2 = f2.getAbsolutePath();
        System.out.println(absolutePath2);
    }

判断功能的方法

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

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

用于判断构造方法中给定的路径是否以文件文件夹结尾

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

用于判断构造方法中给定过的路径是否以文件结尾

注意:

​ 电脑中的硬盘中只有文件/文件夹,两个方法是互斥的

​ 这个两个方法使用前提,路径必须是存在的否则都返回false

创建删除功能的方法

· public boolean creatNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件

· public boolean delete():删除由此File表示的文件或目录

· public boolean mkdir():创建由此File表示的目录

· public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录

代码显示如下:

/**
 * 创建删除功能的方法
 * ·   public boolean    creatNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件
 * ·   public boolean    delete():删除由此File表示的文件或目录
 * ·   public boolean    mkdir():创建由此File表示的目录
 * ·   public boolean    mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录
*/
public class Demo04File {
    public static void main(String[] args) throws IOException {
        show03();
    }

    /**
     * public  boolean    delete():删除由此File表示的文件或目录
     * 此方法可以删除构造方法路径给出的文件/文件夹
     * 返回值:布尔值
     *  true:文件/文件夹删除成功。返回true
     *  false:文件夹中有内容,不会删除返回false;构造方法中路径不存在返回false
     *
     *  注意:delete方法是直接再硬盘删除文件/文件夹,不走回收站,删除需谨慎
    */
    private static void show03() {
        File f1 = new File("D:\\Learn\\javaAgain\\src\\year21Month02\\FileAndRecursion\\aaa");
        boolean delete = f1.delete();
        System.out.println(delete);

    }

    /**
 * public  boolean    mkdir():创建由此File表示的目录
 * public  boolean    mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录
 *
 * 创建文件夹的路径和名称再构造方法中给出(构造方法的参数)
 *     返回值:布尔值
 *     true:文件夹不存在,创建文件夹,返回true
 *     false:文件夹不存在,不会创建,返回false;构造方法中给出路径不存在返回false
 *     注意:
 *     1、此方法只能创建文件夹,不能创建文件
*/
    private static void show02() {
        File f1 = new File("D:\\Learn\\javaAgain\\src\\year21Month02\\FileAndRecursion\\aaa");
        boolean mkdir1 = f1.mkdir();
        System.out.println(mkdir1);
    }

    /**
 *     public boolean    creatNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件
 *     创建文件的路径和名称再构造方法中给出(构造方法的参数)
 *     返回值:布尔值
 *     true:文件不存在,创建文件,返回true
 *     false:文件不存在,不会创建,返回false
 *     注意:
 *     1、此方法只能创建文件,不能创建文件夹
 *     2、创建文件的路径必须存在,否则会抛出异常
*/
    private static void show01() throws IOException {
        File f1 = new File("D:\\Learn\\javaAgain\\src\\year21Month02\\FileAndRecursion\\1.txt");
        boolean newFile = f1.createNewFile();
        System.out.println(newFile);

    }
}

1.4 目录的遍历

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

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

代码演示如下:

/**
 * ·   public String[]   list():    返回一个String数组,表示该File目录中的所有的子文件或目录
 * ·   public File[] listFiles():   返回一个File数组,表示该File目录中的所有的子文件或目录
 *
 * 注意:
 * list方法和listFiles方法遍历的是构造方法中给出的目录
 * 如果构造方法中给出的目录的路径不存在,会抛出空指针异常
 * 如果构造方法中给出的路径不是一个目录,也会抛出空指针异常
*/
public class Demo05File {
    public static void main(String[] args) {
        show01();
    }

    /**
     * public  File[] listFiles():   返回一个File数组,表示该File目录中的所有的子文件或目录
     * 遍历构造方法中给出的目录,会获取目录中所有的文件/文件夹,把文件/文件夹封装为File对象,多个File对象存储到File数组中
     *
     */
    private static void show02() {
        File f1 = new File("D:\\Learn\\javaAgain\\src\\year21Month02\\FileAndRecursion");
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
        //D:\Learn\javaAgain\src\year21Month02\FileAndRecursion\File
        //D:\Learn\javaAgain\src\year21Month02\FileAndRecursion\zz.java
    }

    /**
     * public  String[]   list():    返回一个String数组,表示该File目录中的所有的子文件或目录
     * 遍历构造方法中给出的目录,会获取目录中所有文件/文件夹名称,把获取到的多个名称存储到一个String类型的数组中
     */
    private static void show01() {
        File f1 = new File("D:\\Learn\\javaAgain\\src\\year21Month02\\FileAndRecursion");
        String[] arr = f1.list();
        for (String fileNames: arr){
            System.out.println(fileNames);
        }
        //File
        //zz.java
    }

第二章 递归

2.1 概述

· 递归:指在当前方法内调用自己的这种现象

· 递归的分类

​ 1、递归分为两种,直接递归和间接递归

​ 2、直接递归称为方法自身调用自己

​ 3、间接递归是A方法调用B方法,B方法调用C方法,C方法调用A方法

· 注意事项

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

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

​ 3、构造方法禁止递归

代码演示:

public class Demo01Recurision {
    public static void main(String[] args) {
        B(1);
    }
    /**
     * 构造方法禁止递归
     *  会直接编译报错,构造方法是创建对象使用的,一般递归会导致内存中有无数多个对象,直接编译报错
    */

    /**
     *在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出
     * Exception in thread "main" java.lang.StackOverflowError
    */
    private static void B(int i) {
        System.out.println(i);
        if (i==20000){
            return;
        }
        B(++i);
    }

    /**
     * 递归要有一定的限定条件,保证递归能够停下来,否则会发生栈内存溢出
     * Exception in thread "main" java.lang.StackOverflowError
    */
    private static void A() {
        System.out.println("A方法");
        A();
    }
}

2.2 递归累加求和

计算1~n的和

/**
 * 练习:
 *          使用递归计算1-n之间的和
*/
public class Demo02Recurision {
    public static void main(String[] args) {
        int result = sum(3);
        System.out.println(result);
    }
    /**
     * 定义一个方法,使用递归计算1-n之间的和
     * 1+2+3...+n
     * n+(n-1)+(n-2)+...+1
     * 已知:
     * 最大值:n
     * 最小值:1
     *
     * 使用递归必须明确:
     * 1、递归的结束条件
     *       获取到1的时候结束
     * 2、递归的目的
     *        获取下一个被加数字(n-1)
    */
    public static int sum(int n){
        //获取到1的时候结束
        if (n==1){
            return 1;
        }
        //获取下一个被加的数字(n-1)
        return n+sum(n-1);

    }
    /**
     * 注意:使用递归求和,main方法调用sum方法,sum方法会一直调用sum方法
     * 导致在内存中有多个sum方法(频繁的创建方法,调用方法,销毁方法)效率低下
     *
     * 所以如果仅仅是计算1-n之间的和,不推荐使用递归,使用for循环集合
    */
}

2.3 递归求阶乘

**· 阶乘:**所有小于及等于该数的正整数的积

n的阶乘:n!=n*(n-1)*...*3*2*1

分析:这与累和类似,只不过换成了乘法运算,需要注意阶乘值符合int类型的范围

代码演示:

/**
 * 练习:
 *      使用递归计算阶乘
 *      n的阶乘:n!=n*(n-1)*...*3*2*1
*/
public class Demo03Recurision {
    public static void main(String[] args) {
        int result = jc(5);
        System.out.println(result);

    }
    /**
     * 定义方法使用递归计算阶乘
     * 5的阶乘:5!=5*(5-1)*(5-2)*(5-3)*(5-4)=5*4*3*2*1
     * 递归结束的条件
     *      获取到1的时候结束
     * 递归的目的
     *      获取下一个被乘的数字(n-1)
     * 方法的参数发生变化
     * 5,4,3,2,1
    */
    public static int jc(int n){
        if (n==1){
            return 1;
        }
        return n*jc(n-1);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ar1y53vz-1616252594294)(D:\Program Files\java笔记\Java自我小结\递归求阶乘原理图.PNG)]

第三章 综合案例

3.1 文件搜索

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

分析:

1、目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录

2、遍历目录时,获取的子文件,通过文件名称,判断是否符合条件

代码演示:

public class Demo04Recurision {
    public static void main(String[] args) {
        //创建File对象
        File file = new File("D:\\Learn\\javaAgain\\src\\year21Month01");

        getAllFile(file);
    }
    /**
     * 定义一个方法,参数传递File类型的目录
     * 方法中对目录进行遍历
    */
    public static void getAllFile(File dir){
        //遍历目录
        File[] files = dir.listFiles();
        for (File file : files) {
            //对遍历到的File对象file进行判断,判断是否是文件夹
            if (file.isDirectory()){
                //如果file是一个文件夹,则继续遍历这个文件夹
                //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可:递归(自己调用自己)
                getAllFile(file);

                //else部分表示file是一个文件
            }else{
                //1、把File对象file转为字符串对象,可以通过file.getPath(),toString方法
                String name = file.getName();
                //2、调用String类中的方法endwith判断字符串是否以.java结尾
                boolean b = name.endsWith(".java");
                //如果是以.java结尾的文件,则输出
                if (b){
                    System.out.println(file);
                }
            }

        }
    }

3.2 文件过滤器优化

java.io.FileFilter是一个接口,是File的过滤器。该接口的对象可以传递给File类的listFiles(FileFilter)作为参数,接口中只有一个方法。

boolean accept(File pathname):测试pathname是否应该包含在当前File目录中,符合则返回true

过滤器的原理

listFiles方法一共做了3件事情:

1、listFiles方法会对构造方法中传递的目录进行遍历,获取目录中的每一个文件/文件夹并封装为File对象

2、listFiles方法会调用参数传递的过滤器中的方法accept

3、listFiles方法会把遍历得到的每一个File对象传递给accept方法的参数pathname

accept方法的返回值是一个布尔值

true:就会把传递过去的File对象保存到数组中

false:不会把传递过去的File对象保存到File数组中

3.3 Lambad优化

猜你喜欢

转载自blog.csdn.net/qq_48424500/article/details/115036883
今日推荐