0基础学JAVA(第八天) 异常 IO流

1.异常

异常:程序中一些程序处理不了的特殊情况

1.分类

  异常分为检查型异常(编译时异常),运行时异常

检查型异常在编译时就会抛出的异常(代码会报错),需要在代码中编写处理方式,大多是和程序之外的资源进行访问 直接继承自Exception

运行时异常在代码运行阶段可能会出现的异常,可以没有明文处理 继承自RuntimeException //运行时异常可以通过代码避免异常的发生 ,原本i/a可以修改代码为if(a!=0){System.out.println(i/a);}else {System.out.println("-------");},这样程序不会报错

异常类 Exception 

见过的:NullPointerException ArrayIndecoutofBoundException 

常见的会报错的异常:

        String str = null;        
        System.out.println(str.length());//NullPointerException
        int i = 12;
        int a = 0;
        System.out.println(i/a);     //ArithmeticException

        String name = "张三";
        boolean b=name.equals(name);   //NullPointerException
        b=name.equals(str);

2.处理异常 

1.try...catch...finally

编译时异常举例:

        File file = new File("D:\\easy.text");
        FileInputStream fis = null;
        try {//尝试捕捉异常   其中可能会抛出异常的代码
            fis = new FileInputStream(file);
        } catch (FileNotFoundException eer) {//捕捉异常后要处理的代码
            System.out.println("---------");
            //eer.printStackTrace();//打印异常日志
        } finally {//无用论是否出现异常都会执行的代码块,一般用在关闭资源
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

2.throws  /自定义异常

throws:声明这个方法可能会抛出的异常,如果有多个异常,可以“,”然后继续写,尽量不要扩展异常类型

throw:是在遇到特殊情况的时候具体抛出某个异常对象

class Student{
    String name ;

    public void  info() throws StudentNameIsNullException {//声明这个方法可能会抛出的异常,如果有多个异常,可以“,”然后继续写,尽量不要扩展异常类型
                                                            //throw是在遇到特殊情况的时候具体抛出某个异常对象
        //name==null是特殊情况,不符合业务需求
        if (name==null){

            throw new StudentNameIsNullException("student name is null");
        }
        System.out.println("我的名字是"+name);

}
public void infoA(){                       //运行时异常可以不捕捉
        if (name==null){
            throw new NullPointerException("name  is  null");
           // throw new RuntimeException();省事可以这样
            //throw new Exception();   但是方法后要throws
        }
}
}
//自定义异常,这是一个检查型异常
class StudentNameIsNullException extends Exception{
    public StudentNameIsNullException(){};
    public StudentNameIsNullException(String msg){
        super(msg);
    }


}
//方法重写:子类对父类继承过来的方法重新定义
//约束:返回值类型  方法名   参数列表不能变
//访问权限只能更开发
//重写抛出的异常只能更精确,范围更小,不能扩大
class BigStudent extends Student{
    @Override
    public void info() throws StudentNameIsNullException  //如果父类方法中抛出三个异常,子类只能更少,可以写有一个或两个或三个,而且不能直接写一个Exception
    {}


}

2.处理多种异常

1.try
 
        try {
            System.out.println(12 / 0);
            Object strA = "";
            System.out.println((Integer) strA);
            fis = new FileInputStream(file);
        } catch (ArithmeticException e) {//出现数学运算异常要执行的代码
            System.out.println("ArithmeticException");
        } catch (ClassCastException e) {
            System.out.println("ClassCastException");
        } catch (FileNotFoundException e) {
            System.out.println("FileNotFoundException");
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
2. catch 
 1.使用|声明多种异常
try {
            System.out.println(12 / 0);
            Object strA = "";
            System.out.println((Integer) strA);
            fis = new FileInputStream(file);
        } catch (ArithmeticException | ClassCastException | FileNotFoundException e) {


        }
2. 向上转型
//2.向上转型
        //catch快声明父类异常,捕捉所有子类异常
        try {
            System.out.println(12 / 0);
            Object strA = "";
            System.out.println((Integer) strA);
            fis = new FileInputStream(file);
        } catch (Exception e) {


        }

3. 执行顺序

1.

catch会优先捕捉放在前面的异常,所以子类要优先往前放,子类异常优先处理,父类异常后置处理

        //catch异常捕捉的顺序   子类异常优先往前放,子类异常优先处理,父类异常后置处理
        try {
           
            int[] arr = new int[2];
            arr[8] = 22;                //ArrayIndexoutof
            String strA = "abc";
            strA.charAt(8);          //StringIndexoutof
             List list = new ArrayList();
            list.remove(8);     //Indexout
        } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("ArrayIndexoutof");         //会输出这句话,ArrayIndexoutofBound异常在前面,先捕捉这个异常
        } catch (StringIndexOutOfBoundsException e) {
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }

 2.

如果ccatch块抛出异常,没有finally块就会中断程序

如果有finally快,程序会继续运行

如果程序finally正常运行并且返回值,程序正常运行

    public static int test() {
        try {
            System.out.println(12 / 0);
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {

            return 3;                       //3
        }                                 //即使程序捕捉到了异常,但是有finally,无论怎样都需要执行finally块,所以返回了一个3
    }

程序finally块中运行不正常,不会有返回值 

    public static int test1() {
        try {
            System.out.println(12 / 0);
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.println(12 / 0);
            return 3;                         //不会有返回值,因为在执行finally的时候又有异常
        }
    }

4. 

1.try不能单独使用,必须要有catch或者finally搭配使用

2.如果在try中没有检查型异常,不能随意的使用catch捕获异常

    public static void testA(){
        try{
            System.out.println(12/0);
        }catch (Exception e){


        }

            }

3.如果只使用try和finally,在try中不能有检查型异常

    public static void testB(){
        File file=null;
        FileInputStream fi=null;
        try{
            System.out.println(12/0);
            //fi=new FileInputStream(file);//这样就不可以
            //不能有检查性异常
        }finally {

        }
    }

2.IO流

流一般是java中对于文件处理   java.io包

我们常见的包有:java.lang   java.util

public static void main(String[] args) {
        //在java中声明一个文件,传入字符串当做文件地址
        File file=new File("D:\\wode9.txt");           //getParents是获取路径  
                                                       getParentsFile获取file对象
        //是否存在该文件
        boolean b=file.exists();
        System.out.println(b);

        if (!b){
            try {
               b= file.createNewFile();          //如果不存在这个文件,就创建一个

               if (b){
                   System.out.println("成功创建文件");   //创建之后输出
               }
            } catch (IOException e) {                   //捕获异常
                e.printStackTrace();
            }

        }
        else {
            file.delete();//删除文件夹的时候,文件夹必须是空的,里面不能有文件或者文件夹
            System.out.println("删除成功"+b);             //如果原本已经存在文件就删除并且输出这句话
        }
        //验证是否是文件
        boolean bool=file.isFile();
        System.out.println("是一个文件"+bool);    

        //是否是文件夹
        boolean boo=file.isDirectory();
        System.out.println(boo);

file=new File("D:\文件\封装范围.png")

 long len=file.length(); 可以得到文件的大小

file.listFiles() 获取某个后缀的所以文件

file.equals() 比较是否是同一个文件

mkdir 前面需要有路径准确在某个位置下载 

mkdirs 检查整个文件夹,哪里没有就创建(只要没有就得创建一个)

1.分类

1.方向

根据输入的方向不同分为输入流和输出流

2.介质

根据流动的介质(单位)不同,分为字符流和字节流 字符流只能读取文本txt .xml .properties .html 字节流可以读取所有的文件类型

3.功能

根据功能不一样 或根据作用不同,分为节点流和工具流 对象流 打印流 数据流

读取文件中的内容:

    public static void readFile(){
        File file=new File("D:\\wode.txt");

        FileInputStream fis=null;
        try {
             fis=new FileInputStream(file);
            byte[] arr=new byte[9];
            //读取多少就转换多少
            int length=0;
            while ((length=fis.read(arr))!=-1){//只要数组中长度不为-1就一直读取
                //arr 中就是读取的数据
               String str= new String(arr,0,length);            //将数组中的字符转换成字符串类型    从0开始读,读取length长度
                //String.valueOf(arr);        //转换成字符串类型
                System.out.print(str+"--------");
            }
        } catch (IOException e) {
            System.out.println("没找到");
        }
        finally {
            if (fis!=null) {
                try {
                    fis.close();                 //关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 缓冲流

public static void readFileBuffer(){
        //文件输入流
      FileInputStream fis=null;
      //缓冲流
      BufferedReader br=null;
      //转换流  字节->字符
      InputStreamReader isr=null;
      //转换流和缓冲流都是工具流

          try {
              fis=new FileInputStream("d:\\wode.txt");//节点流
              isr=new InputStreamReader(fis);
              br=new BufferedReader(isr);
              String line=br.readLine();
              System.out.println(line);
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              if (fis != null) {
                  try {
                      fis.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
  }

 从程序向外写:

//往外写
    public static void writeFile(){
        String str="我很帅";
        byte[] arr=str.getBytes();
        FileOutputStream fos=null;
        try {
            fos=new FileOutputStream("d:\\wode.txt",true);//添加true之后可以在原来情况下追加(默认是覆盖)
            fos.write(arr);
        }catch (IOException e){
            e.printStackTrace();

        }
        finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 序列化

public static void main(String[] args) {
        writeObject();
       
    }
    String name;
    String sex;
    int salary;

    @Override
    public String toString() {
        return "Staff{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", salary=" + salary +
                '}';
    }
    
public static void writeObject(){
        //将内存对象转换成序列(流),序列化   字节流
        //这个对象必须是可序列化的
        Staff staff=new Staff();
        staff.name="张三";
        staff.sex="男";
        staff.salary=3500;
        ObjectOutputStream oos=null;
        FileOutputStream fos=null;

        try {
            fos=new FileOutputStream("d:\\wode.txt");
            oos=new ObjectOutputStream(fos);
            oos.writeObject(staff);
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (oos!=null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

反序列化

public static void main(String[] args) {
       
        readObject();
    }
    String name;
    String sex;
    int salary;

    @Override
    public String toString() {
        return "Staff{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", salary=" + salary +
                '}';
    }

public static void readObject(){
        //将对象序列读入程序,转换成对象的方式称为反序列化           序列和反序列的对象都必须实现Serializable(这样就是可以序列化的),但是序列化和反序列化返回的不是一个对象,反序列化回创建新的对象,两个对象用equals不相等
        //创建对象的方式
        //1.new
        //2.clone
        //3.反序列化
        //4.反射
        FileInputStream fis=null;
        ObjectInputStream ois=null;
        try {
            fis=new FileInputStream("d:\\wode.txt");
            ois= new ObjectInputStream(fis);
            Object obj=ois.readObject();
            System.out.println(obj);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois!=null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值