Java学习笔记===》22.异常、File、综合案例

异常、file、综合案例

一、异常

1.什么是异常

​ 异常:就是代表程序出现的问题

​ 误区:不是让我们以后不出先异常,而是程序出了一场之后我们该如何人取处理

在这里插入图片描述

(1)Error

代表的系统级别错误,属于严重问题,系统一旦出现问题,sun公司会把这些错误封装成Error对象,Error是给sun公司自己用的,不是给我们程序员的,因此开发人员不用管他

(2)异常Exception

Exception:叫做异常,代表程序可能出现的问题,我们通常会用Exception以及他的子类来哦封装程序出现的问题

①RuntimeException:

​ RuntimeException本身以及子类在运行时期就会出现错误提示,编译阶段不会出现异常提醒。运行时出现异常,一般都是由于参数传递错误带来的问题,例如:数组索引越界异常

②其他异常:

​ 编译阶段就会出现的异常,例如日期解析异常,没有继承于RuntimeException的异常,直接继承于Exception,编译阶段就会有错误提示

在这里插入图片描述

2.异常在代码中的作用

(1)一场是用来查询bug的关键参考信息

public class ExcrptionTest01 {
    public static void main(String[] args) {
       /* 异常的作用
       (1)一场是用来查询bug的关键参考信息
       (2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况*/

        Student [] arr = new Student[3];
        String name = arr[0].getName();
        System.out.println(name);
        //报错信息
        NullPointerException:   //空指针异常
        Cannot invoke "com_07Gather_jinjie._04Exception.Student.getName()"//不能执行这个方法
        because "arr[0]" is null //因为 arr[0] 是空值
        at com_07Gather_jinjie._04Exception.ExcrptionTest01.main(ExcrptionTest01.java:10)//具体代码出现错误的位置,在com_07Gather_jinjie._04Exception包里面的ExcrptionTest01类里面的main方法的第10行
    }
}
public class ExceptionTest02 {
    public static void main(String[] args) {
        /* 异常的作用
       (1)一场是用来查询bug的关键参考信息
       (2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况*/

        Student2 stu = new Student2("张三,23");
        System.out.println(stu);

        Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
        Index 1 out of bounds for length 1  //索引越界异常,1索引超出了数组长度1
        at com_07Gather_jinjie._04Exception.Student2.<init>(Student2.java:15)
        at com_07Gather_jinjie._04Exception.ExceptionTest02.main(ExceptionTest02.java:9)
    }
}

(2)异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况

package com_07Gather_jinjie._04Exception;

public class ExceptionTest03 {
    public static void main(String[] args) {
        /*
            异常作用一:异常是用来查询bug的关键参考信息
            异常作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况
        */


        //1.创建学生对象
        Student s1 = new Student();
        //年龄:(同学) 18~40岁
        s1.setAge(88);//就知道了50赋值失败
        //选择1:自己悄悄处理
        //选择2:打印在控制台上
        
        //构造方法里对年龄做出限制
       /* public void setAge(int age) {
            if (age > 50 || age < 18) {
                System.out.println("年龄赋值失败");
                throw new RuntimeException();
            } else {
                this.age = age;
            }
        }*/

        /*年龄赋值失败
        Exception in thread "main" java.lang.RuntimeException
        at com_07Gather_jinjie._04Exception.Student.setAge(Student.java:50)
        at com_07Gather_jinjie._04Exception.ExceptionTest03.main(ExceptionTest03.java:14)*/
    }
}

3.异常的处理方式

(1)JVM虚拟机默认的处理方式

🔺把异常的名称,异常原因及异常出现的位置等信息输出在了控制台上

🔺遇到异常,程序会停止执行,下面的代码也不会执行了

public class ExceptionTest04 {
    public static void main(String[] args) {
      
        System.out.println("狂踹瘸子那条好腿");
        System.out.println(2/0);//算术异常 ArithmeticException
        System.out.println("是秃子终会发光");
        System.out.println("火鸡味锅巴");
      
        /*
狂踹瘸子那条好腿
Exception in thread "main" java.lang.ArithmeticException: / by zero
atcom_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest04.main(ExceptionTest04.java:13)*/
//抛出异常后,下面的代码不会执行
    }
}

(2)自己处理(捕获异常)

①格式
try{
    可能出现异常的代码;
} catch(异常类名 变量名){
    异常的处理代码;
}
②目的:

​ 当代码出现异常时,不会停止虚拟机,可以让程序继续往下执行

public class ExceptionTest05 {
    public static void main(String[] args) {
     
        int[] arr = {1, 2, 3, 4, 5, 6};
        try{
            //可能出现异常的代码;
            System.out.println(arr[10]);//此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
            //new ArrayIndexOutOfBoundsException();
            //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象
            //如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码
            //当catch里面所有的代码执行完毕,继续执行try...catch体系下面的其他代码
        }catch(ArrayIndexOutOfBoundsException e){
            //如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
            System.out.println("索引越界了");
        }

        System.out.println("看看我执行了吗?");

    }
}
③可能遇到的为问题

🔺如果try模块中没有遇到问题,代码怎么执行

​ 如果try中没有遇到问题,会把try里面所有的代码全部执行完毕,不会执行catch里面的代码
​ 注意:只有当出现了异常才会执行catch里面的代码

public class ExceptionTest06 {
    public static void main(String[] args) {
       

        int[] arr = {1, 2, 3, 4, 5, 6};
        try{
            System.out.println(arr[0]);//1
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }
        System.out.println("看看我执行了吗?");//看看我执行了吗?
    }
}
//控制台输出
1
看看我执行了吗?

🔺如果try中可能会遇到多个问题,怎么执行

​ 如果try中可能会遇到多个问题,会写多个catch与之对应
​ 细节: 如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面

了解性:

​ 在JDK7之后,我们可以在catch中同时捕获多个异常,中间用|进行隔开
​ 表示如果出现了A异常或者B异常的话,采取同一种处理方案

public class ExceptionTest07 {
    public static void main(String[] args) {
        //JDK7
        int[] arr = {1, 2, 3, 4, 5, 6};

        try{
            System.out.println(arr[10]);//ArrayIndexOutOfBoundsException
            System.out.println(2/0);//ArithmeticException
            String s = null;
            System.out.println(s.equals("abc"));
        }catch(ArrayIndexOutOfBoundsException | ArithmeticException e){
            System.out.println("索引越界了");
        }catch(NullPointerException e){
            System.out.println("空指针异常");
        }catch (Exception e){
            System.out.println("Exception");
        }

        System.out.println("看看我执行了吗?");
    }
}
//控制台输出
索引越界了
看看我执行了吗?

🔺如果try中遇到的问题没有被捕获,怎么执行

自己处理(捕获异常)灵魂三问:
​ 如果try中遇到的问题没有被捕获,相当于try…catch的代码白写了,最终还是会交给虚拟机进行处理

public class ExceptionTest08 {
    public static void main(String[] args) {
      
        int[] arr = {1, 2, 3, 4, 5, 6};

        try{
            System.out.println(arr[10]);//new ArrayIndexOutOfBoundsException();
        }catch(NullPointerException e){
            System.out.println("空指针异常");
        }
        System.out.println("看看我执行了吗?");
    }
}

//控制台输出
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6
	at com_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest08.main(ExceptionTest08.java:16)

🔺如果try中遇到了问题,那么try模块中下面的其他代码还会执行吗

自己处理(捕获异常)灵魂四问:
​ 如果try中遇到了问题,那么try下面的其他代码还会执行吗?
​ 下面的代码就不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体
​ 但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理

public class ExceptionTest09 {
    public static void main(String[] args) {
        
        int[] arr = {1, 2, 3, 4, 5, 6};

        try{
            System.out.println(arr[10]);
            System.out.println("看看我执行了吗?... try");
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界了");
        }
		//try会拿到第一个遇见的异常对象,去往catch寻找,不会再回到try了,因此try中第一个异常下面的其他异常不会生效
        System.out.println("看看我执行了吗?... 其他代码");
    }
}
//控制台输出
索引越界了
看看我执行了吗?... 其他代码
④异常中的常见方法
★Throwable的成员方法
方法名称说明
public String getMessage()返回次throwable的详细消息字符串
public String toString()返回此可抛出的简短描述
public voidprintStackTrace()把异常的错误信息输出在控制台
public class ExceptionTest10 {
    public static void main(String[] args) {

        int []arr = {1,2,3,4,5};

        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            String message = e.getMessage();
            System.out.println(message);
            /*Index 10 out of bounds for length 5
            看看我执行了吗*/

            String str = e.toString();
            System.out.println(str);
            /*java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
            看看我执行了吗*/

            e.printStackTrace();不会停止虚拟机
            /*java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
           at com_07Gather_jinjie._04Exception._01ExceptionTest.ExceptionTest10.main(ExceptionTest10.java:14)
            看看我执行了吗*/

        }

        System.out.println("看看我执行了吗");
    }
}

★为什么printStackTrace方法会以红色的字体打印在控制台呢

​ 在底层是利用System.err.println进行输出,把异常的错误信息以红色字体输出在控制台上

​ 细节:仅仅是打印信息,不会停止程序运行

(3)抛出异常

①throws

注意:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常

public void 方法()throws 异常类名1,异常类名2 . . . {
    . . .
}

★编译时异常:必须要写

★运行时异常:可以不写

②throw

注意:卸载方法里面,结束方法,手动抛出异常对象,交给调用者,方法下面的代码不再执行l

public void 方法(){
    throw new NullPointerException();
}
package com_07Gather_jinjie._04Exception._01ExceptionTest;

public class ExceptionTest11 {
    public static void main(String[] args) {
        /*
        throws:写在方法定义处,表示声明一个异常。告诉调用者,使用本方法可能会有哪些异常。
        throw :写在方法内,结束方法。手动抛出异常对象,交给调用者。方法中下面的代码不再执行了。

        需求:
            定义一个方法求数组的最大值
*/


        int[] arr = null;
        int max = 0;
        try {
            max = getMax(arr);
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("索引越界异常");
        }

        System.out.println(max);


    }


    public static int getMax(int[] arr)/* throws NullPointerException,ArrayIndexOutOfBoundsException*/ {
        if (arr == null) {
            //手动创建一个异常对象,并把这个异常交给方法的调用者处理
            //此时方法就会结束,下面的代码不会再执行了
            throw new NullPointerException();
        }

        if (arr.length == 0) {
            //手动创建一个异常对象,并把这个异常交给方法的调用者处理
            //此时方法就会结束,下面的代码不会再执行了
            throw new ArrayIndexOutOfBoundsException();
        }


        System.out.println("看看我执行了吗?");
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

4.练习

需求:
​ 键盘录入自己心仪的女朋友姓名和年龄。
​ 姓名的长度在 3 - 10之间,
​ 年龄的范围为 18 - 40岁,
​ 超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
​ 提示:
​ 需要考虑用户在键盘录入时的所有情况。
​ 比如:录入年龄时超出范围,录入年龄时录入了abc等情况

package com_07Gather_jinjie._04Exception._02ExceptionTest.Test01;

public class GirlFriend {
    private String name;
    private int age;

    public GirlFriend() {
    }

    public GirlFriend(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        if (name.length() > 10 || name.length() < 3) {
            throw new RuntimeException();
        } else {
            this.name = name;
        }
    }

    /**
     * 获取
     *
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     *
     * @param age
     */
    public void setAge(int age) {
        if (age > 40 || age < 18) {
            throw new RuntimeException();
        } else {
            this.age = age;
        }
    }

    public String toString() {
        return "GirlFriend{name = " + name + ", age = " + age + "}";
    }
}
//测试类
import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);

        GirlFriend gf = new GirlFriend();

        while (true) {
            try {
                System.out.println("请输入你女朋友的姓名");

                gf.setName(sc.nextLine());

                System.out.println("请输入你女朋友的年龄");

                gf.setAge(Integer.parseInt(sc.nextLine()));

                System.out.println(gf);
                //如果所有数据都是正确的,跳出循环
                break;
            } catch (NumberFormatException e) {
                e.printStackTrace();
                continue;
            } catch (RuntimeException e) {
                System.out.println("姓名的长度或者年龄的范围有误");
                continue;
            }
        }
    }
}

5.自定义异常

(1)自定义异常的步骤:

①定义异常类(类名要见名知意)

②写继承关系

③空参构造

④带参构造

🔺意义:就是为了让控制台的报错信息更加的见名知意

//定义异常类
public class NameFormatException extends RuntimeException{
    //起名的技技巧:
    //NameFormat:姓名格式化问题
    //Exception:当前类是一个异常类

    //运行时异常:extends RuntimeException    核心:表示由于参数问题导致的异常
    //编译时异常:extends Exception 核心:提醒程序员检查本地信息


    public NameFormatException() {
    }

    public NameFormatException(String message) {
        super(message);
    }

    public NameFormatException(String message, Throwable cause) {
        super(message, cause);
    }

    public NameFormatException(Throwable cause) {
        super(cause);
    }

    public NameFormatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
//定义第二个异常类
package com_07Gather_jinjie._04Exception._02ExceptionTest.Test02;

public class AgeOutOfBoundsException extends RuntimeException{

    public AgeOutOfBoundsException() {
    }

    public AgeOutOfBoundsException(String message) {
        super(message);
    }

    public AgeOutOfBoundsException(String message, Throwable cause) {
        super(message, cause);
    }

    public AgeOutOfBoundsException(Throwable cause) {
        super(cause);
    }

    public AgeOutOfBoundsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

//测试类
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        /*
            需求:
                键盘录入自己心仪的女朋友姓名和年龄。
                姓名的长度在 3 - 10之间,
                年龄的范围为 18 - 40岁,
                超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
            提示:
                需要考虑用户在键盘录入时的所有情况。
                比如:录入年龄时超出范围,录入年龄时录入了abc等情况
        */
        Scanner sc = new Scanner(System.in);

        GirlFriend gf = new GirlFriend();

        while (true) {
            try {
                System.out.println("请输入你女朋友的姓名");

                gf.setName(sc.nextLine());

                System.out.println("请输入你女朋友的年龄");

                gf.setAge(Integer.parseInt(sc.nextLine()));

                System.out.println(gf);
                //如果所有数据都是正确的,跳出循环
                break;
            } catch (NumberFormatException e) {
                e.printStackTrace();
                continue;
            } catch (AgeOutOfBoundsException e) {
                e.printStackTrace();
                continue;
            }
        }
    }
}
//姓名格式异常
Exception in thread "main" com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.NameFormatException: hfksdhfkqashf格式有误,长度范围3<=name.length()<=10
	at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.GirlFriend.setName(GirlFriend.java:31)
	at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.Test.main(Test.java:25)
//年龄范围异常
    com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.AgeOutOfBoundsException: 67超出范围
	at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.GirlFriend.setAge(GirlFriend.java:53)
	at com_07Gather_jinjie._04Exception._02ExceptionTest.Test02.Test.main(Test.java:29)

二、File

1.什么是File

★File对象就白哦是一个路径,可以是文件的路径,也可以是文件夹的路径

★这个路径可以是存在的,也可以是不存在的

(1)常见的File类构造方法

方法名称说明
public File(String pathname)根据文件路径创建文件对象
public File(String parent,String child)根据父路径名字符串和子路径名字符串创建文件对象
public File(File parent,String child)根据父路径对应文件对象和子路径名字符串创建文件对象
import java.io.File;

public class FileTets01 {
    public static void main(String[] args) {

        //1.public File(String pathname)            | 根据文件路径创建文件对象
        File f1 = new File("C:\\User\\kinbow\\Desktop");
        System.out.println(f1);



        //2.public File(String parent,String child) | 根据父路径名字符串和子路径名字符串创建文件对象
        //以"C:\\User\\kinbow\\Desktop\\a.txt"中的a.txt为例
        //父级路径:C:\\User\\kinbow\\Desktop
        //子级路径:a.txt
        String parent = "C:\\User\\kinbow\\Desktop";
        String child = "a.txt";
        File f2 = new File(parent,child);
        System.out.println(f2);

        //自己拼接
        File f3 = new File(parent+"\\"+child);
        System.out.println(f3);


        //3.public File(File parent,String child)   | 根据父路径对应文件对象和子路径名字符串创建文件对象

        File parent2 = new File("C:\\User\\kinbow\\Desktop");
        String child2 = "a.txt";
        File f4 = new File(parent2,child2);
        System.out.println();
    }
}

(2)小结

①File表示什么

★File对象表示路径,可以是文件、也可以是文件夹。

★这个路径可以是存在的,也可以是不存在的

②绝对路径和相对路径是什么意思

★绝对路径是带盘符的

★相对路径是不带盘符的,默认到当前项目下去找

③File三种构造方法的作用

★public File(String pathname) ===》把字符串表示的路径变成File对象

★public File(String parent,String child) ===》把父级路径和子级路径进行拼接

★public File(File parent,String child) ===》把父级路径和子级路径进行拼接

2.File的常见成员方法

(1)(判断、获取)

方法名称说明
public boolean isDirectory()判断此路径名表示的File是否为文件夹
public bolean isFile()判断此路径名表示的File是否为文件
public boolean exists()判断此路径名表示的File是否存在
public long length()返回文件的大小(字节数量)
public String getAbsolutePath()返回文件的绝对路径
public String getPath()返回定义文件时使用的路径
public String getName()返回文件的名称,带后缀
public long lastModified()返回文件的最后修改时间(时间毫秒值)
import java.io.File;
import java.text.SimpleDateFormat;

public class FileTest02 {
    public static void main(String[] args) {
  /*方法名称                          | 说明                                 |
| --------------------------------- | ------------------------------------ |
| public boolean isDirectory()      | 判断此路径名表示的File是否为文件夹   |
| public bolean isFile()            | 判断此路径名表示的File是否为文件     |
| public boolean exists()         | 判断此路径名表示的File是否存在       |
| public long length()            | 返回文件的大小(字节数量)           |
| public String getAbsolutePath() | 返回文件的绝对路径                   |
| public String getPath()         | 返回定义文件时使用的路径             |
| public String getName()         | 返回文件的名称,带后缀               |
| public long lastModified()      | 返回文件的最后修改时间(时间毫秒值) |
*/

        //判断的方法
        //1.对一个文件的路径进行判断
        File f1 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
        System.out.println(f1.isDirectory());//false
        System.out.println(f1.isFile());//true
        System.out.println(f1.exists());//true
        System.out.println("\n"+"--------------------------------------------------");
        //2.对一个文件夹的路径进行判断
        File f2 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\ccc");
        System.out.println(f2.isDirectory());//true
        System.out.println(f2.isFile());//false
        System.out.println(f2.exists());//true
        System.out.println("\n"+"--------------------------------------------------");
        //3.对一个不存在的路径进行判断
        File f3 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\c.txt");
        System.out.println(f3.isDirectory());//false
        System.out.println(f3.isFile());//false
        System.out.println(f3.exists());//false
        System.out.println("\n"+"--------------------------------------------------");


        //获取的方法
        //1.public long length()            | 返回文件的大小(字节数量)
        //这个方法只能获取文件的大小,不能获取文件夹的大小,
        //如果我们要获取一个文件及的大小,那么需要把这个文件及里面所有的文件大小都累加在一起
        File f4 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
        long length = f4.length();
        System.out.println(length); //12字节
        System.out.println("\n"+"--------------------------------------------------");
        File f5 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\bbb");
        long length2 = f4.length();
        System.out.println(length); //0
        System.out.println("\n"+"--------------------------------------------------");

        //2.public String getAbsolutePath() | 返回文件的绝对路径
        File f6 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
        File absoluteFile = f6.getAbsoluteFile();
        System.out.println(f6);//D:\workspace\idea_space\Java_based\study\src\com_07Gather_jinjie\_05File\aaa\a.txt
        System.out.println("\n"+"--------------------------------------------------");


        //3. public String getPath()         | 返回定义文件时使用的路径
        String path = f6.getPath();
        System.out.println(path);//java\aaa\a.txt
        System.out.println("\n"+"--------------------------------------------------");


        //4.public String getName()         | 返回文件的名称,带后缀
        //细节:
        //1.如果调用处是文件,那么返回的是文件名和后缀名
        //2.如果调用处是文件夹,那么返回的是文件夹的名字
        String name1 = f5.getName();
        String name2 = f6.getName();
        System.out.println(name1);//bbb
        System.out.println(name2);//a.txt==>a:文件名  .txt:扩展名、后缀名
        System.out.println("\n"+"--------------------------------------------------");


        //5. public long lastModified()      | 返回文件的最后修改时间(时间毫秒值)
        long time = f6.lastModified();
        System.out.println(time);//1685633005671

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String format = sdf.format(time);
        System.out.println(format);
    }
}

(2)创建、删除

方法名称说明
public boolean createNewFile()创建一个新的空文件
public boolean mkdir()创建单级文件夹
public boolean mkdirs()创建多级文件夹
public boolean delete()删除文件、空文件夹

注意:delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站

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

public class FileTest03 {
    public static void main(String[] args) throws IOException {
        //1.public boolean createNewFile() | 创建一个新的空的文件
        //细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true
        //     如果当前路径表示的文件是存在的,则创建失败,方法返回false
        //细节2:如果父级路径是不存在的,那么方法会有异常,IOException:系统找不到指定的路径
        //细节3:createNewFile()方法创建的一定是文件,如果路径当中不包含路径名,则会创建一个没有后缀名的而文件
        File f1 = new File("D:\\abc.txt");
        boolean b1 = f1.createNewFile();
        System.out.println(b1);

        //2.public boolean mkdir()         | 创建单级文件夹(目录)
        //细节1:Windows当中路径是唯一的,如果当前路径已经存在则无法创建,返回false
        //细节2:mkdir方法啊只能创建单击文件夹,不能创建多级文件夹
        File f2 = new File("D:\\ada");
        boolean b2 = f2.mkdir();
        System.out.println(b2);

        //3.public boolean mkdirs()        | 创建多级文件夹
        //细节:mkdirs方法奴尽可以创建单击文件夹,也可以创建多级文件夹
        File f3 = new File("D:\\bbb\\aaa\\ccc");
        boolean b3 = f3.mkdirs();
        System.out.println(b3);

        //4.public boolean delete()        | 删除文件、空文件夹
        //细节:
        //1.如果删除的是文件,那么直接删除,不走回收站,会彻底删除
        //2.如果删除的是空文件夹,则直接删除,不走回收站
        //3.如果删除的文件夹里面有文件或者有子文件夹,那么会删除失败,方法返回false
        File f4 = new File("D:\\bbb\\aaa\\ccc" );
        boolean b4 = f4.delete();
        System.out.println(b4);
    }
}

(3)获取并遍历

方法名称说明
public File [ ] listFiles()获取当前该路径下所有内容(重点掌握)
public String [ ] list()获取当前该路径下所有内容
public static File [ ] listRoots()列出可用的文件系统权限
public String [ ] list(FilenameFilter filter)利用文件名过滤器获取当前该路径下所有内容
public File [ ] listFiles(FileFilter filter)利用文件名过滤器获取当前该路径下所有内容
public File [ ] listFiles(FilenameFilter filter)利用文件名过滤器获取当前该路径下所有内容
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Arrays;

public class FileTest04 {
    public static void main(String[] args) {

   /*  public File [ ] listFiles()获取当前该路径下所有内容(重点掌握)
   * 细节:
   * 1.当调用者File表示的路径不存在时,返回null
   * 2.当调用者File表示的路径是文件时,返回null
   * 3.当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
   * 4.当调用者File表示的路径是一个有内容的文件夹时,将里面的所有文件和文件夹的路径放在File数组中返回
   * 5.当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
   * 6.当调用者File表示的路径是需要权限才能访问的文件夹时。返回null
   * */

        //1.创建File对象
        File f1 = new File("D:\\aaa");
        //2.listFiles()  获取文件夹里面的所有内容包括文件夹和文件
        File[] files = f1.listFiles();
        for (File file : files) {
            //这里的file表示当前文件夹里面的每一个文件或文件夹
            System.out.println(file);
        }
        System.out.println("\n"+"===================================================");

        //2.public String [ ] list()  | 获取当前该路径下所有内容(但是仅仅能获取名字)
        File f2 = new File("D:\\aaa");
        String[] arr2 = f2.list();
        for (String s : arr2) {
            System.out.println(s);  //a.txt  aaa  abc.txt  bbb
        }


        System.out.println("\n"+"===================================================");

        //3.| public static File [ ] listRoots()                | 列出可用的文件系统根
        File[] arr = File.listRoots();
        System.out.println(Arrays.toString(arr)); //[C:\, D:\, E:\, F:\]

        System.out.println("\n"+"===================================================");


        //4. public String [ ] list(FilenameFilter filter)     | 利用文件名过滤器获取当前该路径下所有内容
        //假如说要获取某个文件夹里面的所有txt文件
        File f3 = new File("D:\\aaa");
        //accept方法的形参,依次表示当前文件夹下面的每一个文件或者文件夹
        //参数一:父级路径
        //参数二:子级路径
        //返回值:如果返回值为true,就表示当前路径保留
        //      如果返回值为falaw,就表示当前路径舍弃
        String[] arr3 = f3.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                File src = new File(dir, name);
                return src.isFile() && name.endsWith(".txt");
            }
        });
        System.out.println(Arrays.toString(arr3)); //[a.txt, abc.txt]


        System.out.println("\n"+"===================================================");


        //5.public File [ ] listFiles(FileFilter filter)     | 利用文件名过滤器获取当前该路径下suoyouneir
        File f4 = new File("D:\\aaa");
        File[] arr4 = f4.listFiles();
        //file依次表示当前文件夹下面的每一个文件夹或者文件
        //第一种方法
        for (File f : arr4) {
            if (f.isFile() && f.getName().endsWith(".txt")){
                System.out.println(f); //D:\aaa\a.txt  D:\aaa\abc.txt
            }
        }
        //第二种方法
        File [] arr5 = f4.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isFile() && pathname.getName().endsWith(".txt");
            }
        });
        System.out.println(Arrays.toString(arr5));

        System.out.println("\n"+"===================================================");


        //6.public File [ ] list Files(FilenameFilter filter) | 利用文件名过滤器获取当前该路径下suoyouneir
        File[] arr6 = f4.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                File src = new File(dir, name);
                return src.isFile() && name.endsWith(".txt");
            }
        });
        System.out.println(Arrays.toString(arr6));
    }
}

三、综合案例

1.需求:在当前模块下的aaa文件夹中创建一个a.txt文件
import java.io.File;
import java.io.IOException;
public class FileTest01 {
    public static void main(String[] args) throws IOException {
     
        File f1 = new File("D:\\workspace\\idea_space\\Java_based\\study\\src\\com_07Gather_jinjie\\_05File\\aaa\\a.txt");
        boolean newFile = f1.createNewFile();
        System.out.println(newFile);
    }
}
2.需求:定义一个方法,找某一个文件夹中,是否有以avi结尾的电影,暂时不考虑子文件夹
import java.io.File;
public class FileTest02 {
    public static void main(String[] args) {
       
        boolean b = searchFile1(new File("D:\\aaa"));
        System.out.println(b);
    }
    public static boolean searchFile1(File file) {
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isFile() && f.getName().endsWith(".avi")) ;
            return true;
        }
        return false;
    }
}
3.需求:找到电脑中所有以avi结尾的电影。(需要考虑子文件夹)
import java.io.File;
public class FileTest03 {
    public static void main(String[] args) {
        /* 
        套路:
            1,进入文件夹
            2,遍历数组
            3,判断
            4,判断*/

        searchAvi();
    }

    public static void searchAvi(){
        //获取本地所有的盘符
        File[] file = File.listRoots();
        for (File f : file) {
            searchFile(f);
        }
    }
    public static void searchFile(File file){
        //进入要查找的文件夹
        File[] files = file.listFiles();
        //遍历数组,依次得到每一个子文件夹
        for (File f : files) {
            if (f.isFile()){
                //判断:如果是文件,就判断是不是以avi结尾的,如果是,打印该文件
                if (f.getName().endsWith(".avi")){
                    System.out.println(f);
                }
            }else{
                //判断,如果是文件夹,就递归,到子文件夹里找
                //再次调用本方法的时候,参数一定是当前文件夹的子文件夹
                searchFile(f);
            }
        }
    }
}
4.需求:删除一个多级文件夹
import java.io.File;
public class FileTest04 {
    public static void main(String[] args) {
        /*
           删除一个多级文件夹
           如果我们要删除一个有内容的文件夹
           1.先删除文件夹里面所有的内容
           2.再删除自己
        */

        File file = new File("D:\\aaa");
        deleteFile(file);
    }

    public static void deleteFile(File file){
        //进入当前文件夹
        File[] files = file.listFiles();
        //遍历,得到当前文件夹里面的每一个文件或者而文件夹
        for (File f : files) {
            //判断,如果当前是文件,就直接删除
            if (f.isFile()){
                f.delete();
            }else {
                //如果是文件夹,就到子文件夹里
                deleteFile(f);
            }
        }
        //子文件夹里面的文件全部删掉了,再删除本身这个文件夹
        file.delete();
    }
}
5.需求统:计一个文件夹的总大小
import java.io.File;
public class FileTest05 {
    public static void main(String[] args) {
        File file = new File("D:\\aaa");
    }
    /*
     * 作用:
     *       统计一个文件夹的总大小
     * 参数:
     *       表示要统计的那个文件夹
     * 返回值:
     *       统计之后的结果
     *
     * 文件夹的总大小:
     *       说白了,文件夹里面所有文件的大小
     * */
    public static long getLen(File file){
        //定义变量进行文件大小的累加
        long len= 0;
        //进入当前文件夹
        File[] files = file.listFiles();
        //遍历
        for (File f : files) {
            //判断:如果当前是文件,就获取长度,赋值给len
            if (f.isFile()){
                len = len +f.length();
            }else {
                //如果是文件夹,就递归,找到子文件夹进行判断,
                //如果这个文件夹是空的,就把大小传递给len
                len = len + getLen(f);
            }
        }
        //将大小len返回
        return len;
    }
}
6.需求:统计一个文件夹中每种文件的个数并打印。(考虑子文件夹)
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class FileTest06 {
    public static void main(String[] args) {
        /*
            打印格式如下:
            txt:3个
            doc:4个
            jpg:6个
        */

        File file = new File("D:\\aaa");
        HashMap<String,Integer> hm = getFileCount(file);
        System.out.println(hm);
    }
    public static HashMap<String,Integer> getFileCount(File src){
        //1.定义集合用来统计
        HashMap<String,Integer> hm = new HashMap<>();
        //2.进入src文件夹
        File[] files = src.listFiles();
        //3.遍历数组
        for (File file : files) {
            //4.判断,如果是文件,统计
            if(file.isFile()){
                //a.txt
                String name = file.getName();
                String[] arr = name.split("\\.");
                if(arr.length >= 2){
                    String endName = arr[arr.length - 1];
                    if(hm.containsKey(endName)){
                        //存在
                        int count = hm.get(endName);
                        count++;
                        hm.put(endName,count);
                    }else{
                        //不存在
                        hm.put(endName,1);
                    }
                }
            }else{
                //5.判断,如果是文件夹,递归
                //sonMap里面是子文件中每一种文件的个数
                HashMap<String, Integer> sonMap = getFileCount(file);
                //hm:  txt=1  jpg=2  doc=3
                //sonMap: txt=3 jpg=1
                //遍历sonMap把里面的值累加到hm当中
                Set<Map.Entry<String, Integer>> entries = sonMap.entrySet();
                for (Map.Entry<String, Integer> entry : entries) {
                    String key = entry.getKey();
                    int value = entry.getValue();
                    if(hm.containsKey(key)){
                        //存在
                        int count = hm.get(key);
                        count = count + value;
                        hm.put(key,count);
                    }else{
                        //不存在
                        hm.put(key,value);
                    }
                }
            }
        }
        return hm;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值