黑马Java——异常、File、综合案例

目录

一、异常

1、异常的分类

1.1、Error

1.2、Exception

1.3、小结

2、编译时异常和运行时异常

2.1、编译时异常

2.2、运行时异常

2.3、为什么异常要分成编译时异常和运行时异常?

2.4、小结(运行时异常和编译时异常的区别)

3、异常的作用

3.1、查看bug的关键参考信息

3.2、作为方法内部的一种特殊返回值

4、JVM默认的处理方式

5、try…catch(捕获异常)

5.1、示例代码

6、灵魂四问

6.1、灵魂一问:如果try中没有遇到问题,怎么执行?

6.2、灵魂二问:如果try中可能会遇到多个问题,怎么执行?

6.3、灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?

6.4、灵魂四问:如果try中遇到了问题,那么try下面的其它代码还会执行吗?

6.5、小结

7、异常中的常见方法

7.1、示例代码

7.2、System.err

8、抛出异常

8.1、示例代码

8.2、小结

9、综合练习

10、自定义异常

二、File

1、File的概述

1.1、路径

1.2、File常见的构造方法

1.2.1 根据文件路径创建文件对象

1.2.2根据父路径名字符串和子路径名字符串创建文件对象

1.2.3根据父路径对应文件对象和子路径名字符串创建文件对象

2、File的常见成员方法

2.1、创建、删除

1.createNewFile() 创建一个新的空的文件,创建成功返回true

2.mkdir   make Directory,文件夹(目录)

3.mkdirs   创建多级文件夹

 4.delete() 删除文件、空文件夹

2.2、获取并遍历

2.3、判断、获取

三、综合练习

1、File类相关的API练习题

1.1、在aaa文件夹中创建一个a.txt文件

1.2、找某一个文件夹中,是否有以avi结尾的电影(不考虑子文件夹)

1.3、找某一个文件夹中,是否有以avi结尾的电影(考虑子文件夹)

1.4、删除一个多级文件夹

1.5、统计一个文件夹的总大小

1.6、统计一个文件夹中每个文件的个数并打印


一、异常

 误区:不是让我们以后不出异常,而是出现异常了之后,如何去处理

1、异常的分类

1.1、Error

1.2、Exception

1.3、小结

2、编译时异常和运行时异常

2.1、编译时异常

2.2、运行时异常

2.3、为什么异常要分成编译时异常和运行时异常?

在编译阶段,Java不会运行代码,只会检查语法是否错误,或者做一些性能的优化

编译时异常更多的是提醒程序员检查本地的信息

运行时异常的核心在于提醒,而是代码出错导致程序出现的问题

2.4、小结(运行时异常和编译时异常的区别)

3、异常的作用

3.1、查看bug的关键参考信息

3.1.1

 

 3.1.2

 

3.2、作为方法内部的一种特殊返回值

 

4、JVM默认的处理方式

 示例代码:

异常:

5、try…catch(捕获异常)

5.1、示例代码

Console:

6、灵魂四问

6.1、灵魂一问:如果try中没有遇到问题,怎么执行?

顺序执行,没有问题,自然就不会触发捕获异常

6.2、灵魂二问:如果try中可能会遇到多个问题,怎么执行?

6.3、灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?

6.4、灵魂四问:如果try中遇到了问题,那么try下面的其它代码还会执行吗?

6.5、小结

7、异常中的常见方法

7.1、示例代码

添加异常处理

7.2、System.err

在控制台中红色打印

 

 

8、抛出异常

8.1、示例代码

package com.yaqi.a01myexception;

public class ExceptionDemo12 {
    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;
    }



}

 

8.2、小结

9、综合练习

 

异常

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


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

 

package com.yaqi.test1;

import java.util.Scanner;

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

        //1.创建键盘录入对象
        Scanner sc =new Scanner(System.in);
        //2.创建女朋友对象
        GirlFriend gf = new GirlFriend();
        while (true) {
            //3.接收女朋友姓名
            try {
                System.out.println("请输入你心仪的女朋友的名字");
                String name = sc.nextLine();
                gf.setName(name);
                //4.接收女朋友的年龄
                System.out.println("请输入你心仪的女朋友的年龄");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                gf.setAge(age);
                //如果所有的数据都是正确的,那么跳出循环
                break;
            } catch (NumberFormatException e) {
                System.out.println("年龄的格式有误,请输入数字");
                //continue;
            }catch(RuntimeException e){
                System.out.println("姓名的长度或者年龄的范围有误");
                //continue;
            }
        }
        
        //5.打印
        System.out.println(gf);

    }
}

 

 

10、自定义异常

NameFormatException.java: 

package com.yaqi.test2;

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


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


    public NameFormatException() {
    }

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

 AgeOutOfBoundsException.java:

package com.yaqi.test2;

public class AgeOutOfBoundsException extends RuntimeException{

    public AgeOutOfBoundsException() {
    }

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

Student类(部分代码):

   /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        int len = name.length();
        if(len < 3 || len > 10){
            throw new NameFormatException(name + "格式有误,长度应该为:3~10");
        }
        this.name = name;
    }
    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        if(age < 18 || age > 40){
            throw new AgeOutOfBoundsException(age + "超出了范围");
        }
        this.age = age;
    }

测试类:

package com.yaqi.test2;

import java.util.Scanner;

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


        //1.创建键盘录入的对象
        Scanner sc = new Scanner(System.in);
        //2.创建女朋友的对象
        GirlFriend gf = new GirlFriend();
        while (true) {
            //3.接收女朋友的姓名
            try {
                System.out.println("请输入你心仪的女朋友的名字");
                String name = sc.nextLine();
                gf.setName(name);
                //4.接收女朋友的年龄
                System.out.println("请输入你心仪的女朋友的年龄");
                String ageStr = sc.nextLine();
                int age = Integer.parseInt(ageStr);
                gf.setAge(age);
                //如果所有的数据都是正确的,那么跳出循环
                break;
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (NameFormatException e) {
                e.printStackTrace();
            }catch (AgeOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
        //5.打印
        System.out.println(gf);


    }
}

 

二、File

1、File的概述

  • File对象就表示一个路径,可以是文件路径、也可以是文件夹路径
  • 这个路径可以是存在的,也允许不存在的

1.1、路径

1.2、File常见的构造方法

1.2.1 根据文件路径创建文件对象
//1.根据字符串表示的路径,变成File对象
        String str = "C:\\Users\\alienware\\Desktop\\a.txt";
        File f1 = new File(str);
        System.out.println(f1);//C:\Users\alienware\Desktop\a.txt
1.2.2根据父路径名字符串和子路径名字符串创建文件对象
//2.父级路径:C:\Users\alienware\Desktop
        //子级路径:a.txt
        String parent = "C:\\Users\\alienware\\Desktop";
        String child = "a.txt";
        File f2 = new File(parent,child);
        System.out.println(f2);//C:\Users\alienware\Desktop\a.txt

 在Java中 \ 表示转义字符,\\才能正确表示路径分隔符

File f3 = new File(parent + "\\" + child);
        System.out.println(f3);//C:\Users\alienware\Desktop\a.txt

1.2.3根据父路径对应文件对象和子路径名字符串创建文件对象

        //3.把一个File表示的路径和String表示路径进行拼接
        File parent2 = new File("C:\\Users\\alienware\\Desktop");
        String child2 = "a.txt";
        File f4 = new File(parent2,child2);
        System.out.println(f4);//C:\Users\alienware\Desktop\a.txt

1.3、小结

2、File的常见成员方法

2.1、创建、删除

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

1.createNewFile() 创建一个新的空的文件,创建成功返回true

//1.createNewFile 创建一个新的空的文件
        //细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true
        //      如果当前路径表示的文件是存在的,则创建失败,方法返回false
        //细节2:如果父级路径是不存在的,那么方法会有异常IOException
        //细节3:createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件
        File f1 = new File("D:\\aaa\\ddd");
        boolean b = f1.createNewFile();
        System.out.println(b);//true

2.mkdir   make Directory,文件夹(目录)

//细节1:windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false
        //细节2:mkdir方法只能创建单级文件夹,无法创建多级文件夹。
        File f2 = new File("D:\\aaa\\aaa\\bbb\\ccc");
        boolean b = f2.mkdir();
        System.out.println(b); //false

3.mkdirs   创建多级文件夹

//3.mkdirs   创建多级文件夹
        //细节:既可以创建单级的,又可以创建多级的文件夹
        File f3 = new File("D:\\aaa\\ggg");
        boolean b = f3.mkdirs();
        System.out.println(b);//true

 4.delete() 删除文件、空文件夹

细节:

如果删除的是文件,则直接删除,不走回收站。
如果删除的是空文件夹,则直接删除,不走回收站
如果删除的是有内容的文件夹,则删除失败
//1.创建File对象
        File f1 = new File("D:\\aaa\\eee");
        //2.删除
        boolean b = f1.delete();
        System.out.println(b);

2.2、获取并遍历

listFIles() 获取当前路径下所有内容(重点掌握,其它了解) 

 

 

listFiles()方法的细节: 

 

listRoots() 获取系统中所有的盘符

 

 list() 获取当前该路径下所有内容(仅仅能获取名字)

通过listFiles()实现文件过滤器的效果:

list(FilenameFilter filter)  利用文件名过滤器获取当前该路径下的所有内容

listFiles(FilenameFilter filter)  利用文件名过滤器获取当前该路径下的所有内容 

2.3、判断、获取

代码示例:

 //1.length  返回文件的大小(字节数量)
        //细节1:这个方法只能获取文件的大小,单位是字节
        //如果单位我们要是M,G,可以不断的除以1024
        //细节2:这个方法无法获取文件夹的大小
        //如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在一起。

package com.yaqi.a01myfile;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileDemo3 {
    public static void main(String[] args) {
     /*
        public long length()                返回文件的大小(字节数量)
        public String getAbsolutePath()     返回文件的绝对路径
        public String getPath()             返回定义文件时使用的路径
        public String getName()             返回文件的名称,带后缀
        public long lastModified()          返回文件的最后修改时间(时间毫秒值)
     */



        //1.length  返回文件的大小(字节数量)
        //细节1:这个方法只能获取文件的大小,单位是字节
        //如果单位我们要是M,G,可以不断的除以1024
        //细节2:这个方法无法获取文件夹的大小
        //如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在一起。

        File f1 = new File("D:\\aaa\\a.txt");
        long len = f1.length();
        System.out.println(len);//12

        File f2 = new File("D:\\aaa\\bbb");
        long len2 = f2.length();
        System.out.println(len2);//0

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

        //2.getAbsolutePath 返回文件的绝对路径
        File f3 = new File("D:\\aaa\\a.txt");
        String path1 = f3.getAbsolutePath();
        System.out.println(path1);

        File f4 = new File("myFile\\a.txt");
        String path2 = f4.getAbsolutePath();
        System.out.println(path2);


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

        //3.getPath 返回定义文件时使用的路径
        File f5 = new File("D:\\aaa\\a.txt");
        String path3 = f5.getPath();
        System.out.println(path3);//D:\aaa\a.txt

        File f6 = new File("myFile\\a.txt");
        String path4 = f6.getPath();
        System.out.println(path4);//myFile\a.txt

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


        //4.getName 获取名字
        //细节1:
        //a.txt:
        //      a 文件名
        //      txt 后缀名、扩展名
        //细节2:
        //文件夹:返回的就是文件夹的名字
        File f7 = new File("D:\\aaa\\a.txt");
        String name1 = f7.getName();
        System.out.println(name1);


        File f8 = new File("D:\\aaa\\bbb");
        String name2 = f8.getName();
        System.out.println(name2);//bbb

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

        //5.lastModified  返回文件的最后修改时间(时间毫秒值)
        File f9 = new File("D:\\aaa\\a.txt");
        long time = f9.lastModified();
        System.out.println(time);//1667380952425

        //如何把时间的毫秒值变成字符串表示的时间呢?
        //课堂练习:
        //yyyy年MM月dd日 HH:mm:ss
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date date = new Date(time);
        System.out.println(sdf.format(date));//1970年01月01日 08:00:00


    }
}

三、综合练习

1、File类相关的API练习题

1.1、在aaa文件夹中创建一个a.txt文件

 

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

public class Test1 {
    public static void main(String[] args) throws IOException {
        //需求:在当前模块下的aaa文件夹中创建一个a.txt文件

        //1.创建a.txt的父级路径
        File file = new File("myfile\\aaa");
        //2.创建父级路径
        //如果aaa是存在的,那么此时创建失败的。
        //如果aaa是不存在的,那么此时创建成功的。
        file.mkdirs();
        //3.拼接父级路径和子级路径
        File src = new File(file,"a.txt");
        boolean b = src.createNewFile();
        if(b){
            System.out.println("创建成功");
        }else{
            System.out.println("创建失败");
        }

    }
}

 

1.2、找某一个文件夹中,是否有以avi结尾的电影(不考虑子文件夹)

package com.yaqi.a02test;

import java.io.File;

public class Test2 {
    public static void main(String[] args) {
        /*需求:
             定义一个方法找某一个文件夹中,是否有以avi结尾的电影。
	        (暂时不需要考虑子文件夹)
        */

        File file = new File("D:\\aaa\\bbb");
        boolean b = haveAVI(file);
        System.out.println(b);
    }
    /*
    * 作用:用来找某一个文件夹中,是否有以avi结尾的电影
    * 形参:要查找的文件夹
    * 返回值:查找的结果  存在true  不存在false
    * */
    public static boolean haveAVI(File file){// D:\\aaa
        //1.进入aaa文件夹,而且要获取里面所有的内容
        File[] files = file.listFiles();
        //2.遍历数组获取里面的每一个元素
        for (File f : files) {
            //f:依次表示aaa文件夹里面每一个文件或者文件夹的路径
            if(f.isFile() && f.getName().endsWith(".avi")){
                return true;
            }
        }
        //3.如果循环结束之后还没有找到,直接返回false
        return false;
    }
}

 

1.3、找某一个文件夹中,是否有以avi结尾的电影(考虑子文件夹)

import java.io.File;

public class Test3 {
    public static void main(String[] args) {
       /* 需求:
        找到电脑中所有以avi结尾的电影。(需要考虑子文件夹)


        套路:
            1,进入文件夹
            2,遍历数组
            3,判断
            4,判断

        */

        findAVI();

    }

    public static void findAVI(){
        //获取本地所有的盘符
        File[] arr = File.listRoots();
        for (File f : arr) {
            findAVI(f);
        }
    }

    public static void findAVI(File src){//"C:\\
        //1.进入文件夹src
        File[] files = src.listFiles();
        //2.遍历数组,依次得到src里面每一个文件或者文件夹
        if(files != null){
            for (File file : files) {
                if(file.isFile()){
                    //3,判断,如果是文件,就可以执行题目的业务逻辑
                    String name = file.getName();
                    if(name.endsWith(".avi")){
                        System.out.println(file);
                    }
                }else{
                    //4,判断,如果是文件夹,就可以递归
                    //细节:再次调用本方法的时候,参数一定要是src的次一级路径
                    findAVI(file);
                }

            }
        }
    }
}

 

1.4、删除一个多级文件夹

 

package com.yaqi.a02test;

import java.io.File;

public class Test4 {
    public static void main(String[] args) {
        /*
           删除一个多级文件夹
           如果我们要删除一个有内容的文件夹
           1.先删除文件夹里面所有的内容
           2.再删除自己
        */

        File file = new File("D:\\aaa\\src");
        delete(file);

    }

    /*
    * 作用:删除src文件夹
    * 参数:要删除的文件夹
    * */
    public static void delete(File src){
        //1.先删除文件夹里面所有的内容
        //进入src
        File[] files = src.listFiles();
        //遍历
        for (File file : files) {
            //判断,如果是文件,删除
            if(file.isFile()){
                file.delete();
            }else {
                //判断,如果是文件夹,就递归
                delete(file);
            }
        }
        //2.再删除自己
        src.delete();
    }


}

1.5、统计一个文件夹的总大小

package com.yaqi.a02test;

import java.io.File;

public class Test5 {
    public static void main(String[] args) {
       /*需求:
            统计一个文件夹的总大小
      */


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

        long len = getLen(file);
        System.out.println(len);//4919189
    }

    /*
    * 作用:
    *       统计一个文件夹的总大小
    * 参数:
    *       表示要统计的那个文件夹
    * 返回值:
    *       统计之后的结果
    *
    * 文件夹的总大小:
    *       说白了,文件夹里面所有文件的大小
    * */
    public static long getLen(File src){
        //1.定义变量进行累加
        long len = 0;
        //2.进入src文件夹
        File[] files = src.listFiles();
        //3.遍历数组
        for (File file : files) {
            //4.判断
            if(file.isFile()){
                //我们就把当前文件的大小累加到len当中
                len = len + file.length();
            }else{
                //判断,如果是文件夹就递归
                len = len + getLen(file);
            }
        }

        return len;


    }




}

 

1.6、统计一个文件夹中每个文件的个数并打印

package com.yaqi.a02test;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test6 {
    public static void main(String[] args) throws IOException {
       /*
            需求:统计一个文件夹中每种文件的个数并打印。(考虑子文件夹)
            打印格式如下:
            txt:3个
            doc:4个
            jpg:6个


        */






        File file = new File("D:\\aaa\\src");
        HashMap<String, Integer> hm = getCount(file);
        System.out.println(hm);
    }

    /*
    * 作用:
    *       统计一个文件夹中每种文件的个数
    * 参数:
    *       要统计的那个文件夹
    * 返回值:
    *       用来统计map集合
    *       键:后缀名 值:次数
    *
    *       a.txt
    *       a.a.txt
    *       aaa(不需要统计的)
    *
    *
    * */
    public static HashMap<String,Integer> getCount(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 = getCount(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、付费专栏及课程。

余额充值