异常处理在IO流中的应用

  • try...catch处理IO流异常的缺陷
  • try..catch...finally
  • try-with-resource

Java异常是Java提供的一种识别及响应错误的一致性机制,java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。---pdai

try...catch...处理IO异常的缺陷

传统的异常处理一般用try...catch..就可以解决,我们来试一下用它来处理IO


当我们的try语句中的write方法出现异常,我们的异常处理语句将会跳转到catch进行处理,这样的话fos.close资源关闭语句将不会被执行,这样的后果将会很严重

try...catch...finally...

可能是为了避免上面的情况发生,java推出了try...catch...finallly...,这个异常处理语句的核心就是finally里面的语句一定会被执行,像一些需要手动关闭的物理资源就可以放到这个语句里面去执行,我们的IO正好可以使用

  • 关于锁释放的举例

但是finally里面的代码也不能保证一定被执行,在以下情况下不会被执行:

  • 在前面的代码中用了System.exit()退出程序。
  • finally语句块中发生了异常。
  • 程序所在的线程死亡。
  • 关闭CPU。

我们来看上面的finally中出现异常的一种情况:

package com;

import java.io.*;
import java.util.Arrays;

public class ByteStreamDemo3 {
    public static void main(String[]args)  {
        //文件的拷贝(提速版):用try...catch..finally进行异常处理

        FileInputStream fis = null;
        FileOutputStream fos = null;
        //如果当创建fis和fos对象时出现异常,将会进行跳转,fis和fos有没有被初始化的风险
        try {
            //1.定义流的对象
          fis =   new FileInputStream("C:\\Data\\a1.txt");
          fos = new FileOutputStream("small\\sss.txt");

            //2.进行拷贝:边读边写
            //定义字节数组
            int len;//第三方变量
            byte[] bytes = new byte[2];//规定其最多一次读取2个字节
            while ((len = fis.read(bytes))!=-1){
                fos.write(bytes,0,len);//读取多少即写入多少
            }
            //3.关闭资源

        } catch (IOException e) {
           e.printStackTrace();
        } finally {//对于资源的关闭语句也可能会出现异常
            //当fos和fis为空也可能出现空指针异常
            if(fos!= null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
           if(fis!=null){
               try {
                   fis.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }

        }

    }
}


在这种情况下,我们的finally语句中的关闭资源的语句也可能会出现异常,假如出现了异常,那么我们的资源就极有可能没有被关闭。

try-with-resource

为了能够安全的关闭资源,在jdk7时候提出了try-with-resource,要求使用try-with-resource的类必须实现AutoCloseable接口

所以实现了AutoCloseable的类的资源可以被自动关闭,不需要手动释放

package com;

import java.io.*;
import java.util.Arrays;

public class ByteStreamDemo3 {
    public static void main(String[]args)  {
        //文件的拷贝(提速版):用try...catch..finally进行异常处理
        //JDK7:io中捕获异常的写法
        /*
        try后面的括号中写创建对象的代码
            注意:只有实现了AutoCloseable接口的类,才能在小括号中创建对象
            try(){

            }catch(){
            }
         */
        try(FileOutputStream fos = new FileOutputStream("small\\sss.txt");
        FileInputStream fis = new FileInputStream("C:\\Data\\a1.txt")){
            //2.进行拷贝:边读边写
            //定义字节数组
            int len;//第三方变量
            byte[] bytes = new byte[2];//规定其最多一次读取2个字节
            while ((len = fis.read(bytes))!=-1){
                fos.write(bytes,0,len);//读取多少即写入多少
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}


使用这个新特性,我们就不需要去手动关闭资源和对关闭资源语句的异常处理了

posted @ 2023-02-22 09:43  一往而深,  阅读(32)  评论(0编辑  收藏  举报