90-JavaIO流释放资源的方式

IO流释放资源的方式

一、使用close()方法释放资源的不足之处

在这里插入图片描述


二、优化方案

1、try-catch-finally
  • finally:在异常处理时提供finally块来执行所有清除操作,比如:IO流中的释放资源。
  • 特点:被finally控制的语句最终一定会执行,除非JVM退出
  • 异常处理标准格式:try…catch…finally
package com.app.d6_release_resource;

import java.io.*;

/**
    目标:学会使用finally释放资源
    finally:无论程序是正常结束,还是出现异常,都要执行finally块的代码
 */
public class TryCatchFinallyDemo01 {
    public static void main(String[] args) {
        // 注意:要想使用finally执行IO流的代码,就需要将管道创建在外面
        // 1、定义一个文件字节输入流
        InputStream is = null;

        // 2、定义一个文件字节输出流
        OutputStream os = null;

        try {

            // System.out.println( 10 / 0 );   // 创建管道之前出现异常!!

            // 1、创建一个文件字节输入流管道与源文件接通
            is = new FileInputStream("day10-file-io-app/src/out03.txt");

            // 2、创建一个文件字节输出流管道与目标文件接通
            os = new FileOutputStream("day10-file-io-app/src/out04.txt");

            // 3、读写数据,拷贝视频
            // 定义一个字节数组存储原视频数据
            byte[] buffer = new byte[1024]; // 1KB
            int len;    // 记录每次读取的字节数。(为了防止数据会多倒出)
            // 定义一个循环,开始将原视频数据拷贝到目标路径下
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);   // 读取多少倒出多少(保证数据的完整性)
            }
            System.out.println("拷贝完成~~");

            System.out.println( 10 / 0 );   // 关闭流之前出现异常!!
            return; // 关闭流之前结束main方法!!

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 无论程序是正常结束,还是出现异常,都要执行这里的代码
            System.out.println("-------finally块代码被执行了--------");

            try {
                // 4、关闭流
                // 注意:关闭前,必须判断一下流是否为null(因为实际开发中会有很多代码,为了防止在创建管道前就出现了异常,判断一下是好事!)
                if (os != null) os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
拷贝完成~~
-------finally块代码被执行了--------
java.lang.ArithmeticException: / by zero
	at com.app.d6_release_resource.TryCatchFinallyDemo01.main(TryCatchFinallyDemo01.java:38)

Process finished with exit code 0


2、面试题可能会出现
package com.app.d6_release_resource;

/**
    扩展:面试题可能会出现
 */
public class TryCatchFinallyDemo02 {
    public static void main(String[] args) {
        // 计算10乘以2的结果
        System.out.println(test(10, 2));
    }

    public static int test(int a, int b) {
        try {
            int c = a / b;
            return c;
        }catch (Exception e) {
            e.printStackTrace();
            return -1;  // 计算结果出现bug,返回-1
        }finally {
            // 哪怕上面有 return语句的执行,也必须先执行完这里的代码才可以!
            // 开发中不建议在这里加 return,因为加了,返回的永远是这里的数据了,这样会出现问题!!
            return 100;
        }
    }
}
100

Process finished with exit code 0



总结

1、try…catch…finally的作用是啥?

  • finally代码块是最终一定要执行的,可以在代码执行完毕的最后用于释放资源比较好!!



3、try-with-resource
  • finally虽然可以用于释放资源,但是释放资源的代码过于繁琐?
  • 有没有办法简化?

在这里插入图片描述


(1)JDK7 和 JDK9 中都简化了资源释放操作

在这里插入图片描述



(2)注意
  • JDK7 以及 JDK9()中只能放置资源对象,否则报错!!
  • 什么是资源呢?
  • 资源都是实现了 Closeable/AutoCloseable接口的类对象。
public abstract class InputStream implements Closeable {}
public abstract class OutputStream implements Closeable, Flushable {}


package com.app.d6_release_resource;

import java.io.*;

/**
    目标:学会使用JDK7的try...catch...resource自动释放资源:推荐使用!
 */
public class TryCatchResourceDemo03 {
    public static void main(String[] args) {
        try (
            // 1、创建一个文件字节输入流管道与源文件接通
            InputStream is = new FileInputStream("day10-file-io-app/src/out03.txt");

            // 2、创建一个文件字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream("day10-file-io-app/src/out04.txt");

            // int a = 123;    // 报错!!因为这里只能放置资源

            MyConnection connection = new MyConnection();   // 最终会自动调用资源的close()方法
        ) {
            // 3、读写数据,拷贝视频
            // 定义一个字节数组存储原视频数据
            byte[] buffer = new byte[1024]; // 1KB
            int len;    // 记录每次读取的字节数。(为了防止数据会多倒出)
            // 定义一个循环,开始将原视频数据拷贝到目标路径下
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);   // 读取多少倒出多少(保证数据的完整性)
            }
            System.out.println("拷贝完成~~");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
    模拟一个连接资源
 */
class MyConnection implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println("连接资源被释放了!!");
    }
}
拷贝完成~~
连接资源被释放了!!

Process finished with exit code 0



(3)JDK9资源释放操作
  • 不建议这种操作!!

在这里插入图片描述


package com.app.d6_release_resource;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
    目标:学会使用JDK9的try...catch...resource自动释放资源:可以了解一下。
 */
public class TryCatchResourceDemo04 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输入流管道与源文件接通
        InputStream is = new FileInputStream("day10-file-io-app/src/out03.txt");

        // 2、创建一个文件字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("day10-file-io-app/src/out04.txt");
        
        try ( is; os ) {
            // 3、读写数据,拷贝视频
            // 定义一个字节数组存储原视频数据
            byte[] buffer = new byte[1024]; // 1KB
            int len;    // 记录每次读取的字节数。(为了防止数据会多倒出)
            // 定义一个循环,开始将原视频数据拷贝到目标路径下
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);   // 读取多少倒出多少(保证数据的完整性)
            }
            System.out.println("拷贝完成~~");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
拷贝完成~~

Process finished with exit code 0




总结

1、try…catch…resource的作用是啥?

  • 自动释放资源、代码简洁
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值