Java IO流 - 释放资源的方式

news2024/11/15 11:52:33

资源释放的方式

书接上文, 在上一篇文章我们做过一个文件拷贝的练习, 但是在联系中是有释放资源隐患的的, 例如在下面代码中, 在文件释放之前有许多行的逻辑代码; 如果这许多行的逻辑代码有报错, 导致程序不运行, 那么资源就得不到释放

public static void main(String[] args) {
    try {
        InputStream inp = new FileInputStream("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.pdf");
        OutputStream oup = new FileOutputStream("/Users/chenyq/Documents/newtest.pdf");

        byte[] arr = inp.readAllBytes();
        oup.write(arr);
        System.out.println("复制成功!");
      
      	// 许多行的逻辑代码

        oup.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

try-catch-finally

为了解决隐患, 我们需要使用try-catch-finally对资源释放进行优化

finally:在异常处理时提供finally块来执行所有清除操作,比如说IO流中的释放资源

特点:被finally控制的语句最终一定会执行(除非JVM退出)

异常处理标准格式:try….catch…finally

try….catch…finally格式:

try {
  	FileOutputStream fos = new FileOutputStream("a.txt");
	  fos.write(97); 
		fos.close(); 
} catch (IOException e) {
  	e.printStackTrace();
} finally {
  
}

使用try….catch…finally优化文件拷贝代码

由于finally中无法访问到 inp和oup, 所以我们需要在外部定义变量将 inp和oup保存起来

public static void main(String[] args) {
    // 在外部保存为了finally中可以访问到
    InputStream inp = null;
    OutputStream oup = null;
  
    try {
        inp = new FileInputStream("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.pdf");
        oup = new FileOutputStream("/Users/chenyq/Documents/newtest.pdf");

        byte[] arr = inp.readAllBytes();
        oup.write(arr);
        System.out.println("复制成功!");

    } catch (IOException e) {
        e.printStackTrace();
    } finally { // finally中释放资源
        try {
            if (inp != null) { // 非空校验
                inp.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (oup != null) { // 非空校验
                oup.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

try-catch-resource

finally虽然可以用于释放资源,但是释放资源的代码过于繁琐, 那么有没有办法可以简化呢?

在这里插入图片描述

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

在这里插入图片描述

JDK7改进方案演示:

在括号中放置资源对象, 并且是只能放置资源对象, 用完会自动关闭: 自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭的操作)

public static void main(String[] args) {
    try(
            InputStream inp = new FileInputStream("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.pdf");
      
            OutputStream oup = new FileOutputStream("/Users/chenyq/Documents/newtest.pdf");
            ) {

        byte[] arr = inp.readAllBytes();
        oup.write(arr);
        System.out.println("复制成功!");

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

JDK9改进方案演示:

弊端: 在try外部定义输入输出流还需要再抛出异常

public static void main(String[] args) throws Exception {
    InputStream inp = new FileInputStream("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.pdf");
    OutputStream oup = new FileOutputStream("/Users/chenyq/Documents/newtest.pdf");
    try(inp; oup) {

        byte[] arr = inp.readAllBytes();
        oup.write(arr);
        System.out.println("复制成功!");

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

注意:

JDK 7 以及 JDK 9的()中只能放置资源对象,否则报错

什么是资源呢?

资源都是实现了Closeable / AutoCloseable接口的类对象

public abstract class InputStream implements Closeable {}

public abstract class OutputStream implements Closeable, Flushable{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Crack:ActiveReportsJS 3.2.2 EN:ActiveReportsJS

ActiveReportsJS - 高级 JavaScript 报告解决方案 ActiveReportsJS 是一种用于在前端应用程序中可视化数据的报告解决方案。Ω578867473自定义报告布局并将我们的报告设计器和查看器组件集成到 Web 应用程序中,以便在任何平台上预览、导出或打印报告。 使用我们的跨…

WPF+ASP.NET SignalR实现动态折线图

在实际业务中,当后台数据发生变化,客户端能够实时的收到通知,而不是由用户主动的进行页面刷新才能查看,这将是一个非常人性化的设计。有没有那么一种场景,后台数据明明已经发生变化了,前台却因为没有及时刷…

ElementUI——案例2用户管理(基于SpringBoot实现增删改)

1.ElementUI整合SpringBoot前后端分离实现用户增删改查 效果展示 2.前端核心代码 项目目录 main.js引入 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import router from ./router import axios from axiosVue.prototype.$http ax…

SQL 存储过程

文章目录存储过程简介存储过程的创建及调用存储过程的删除 如何删除存储过程存储过程的优缺点现需要向学生表中插入新的学生数据。但在插入学生数据的时,需要同 时检查老师表里的数据。如果插入学生的老师不在老师表里,则先向老师表中插入一条老师数据&a…

高级IO-多路转接

高级IO 以前的都是拷贝接口。write什么的就是将字符串拷贝到发送缓冲区中。 应用层等待接收缓冲区填写数据的过程算是IO吗?算 IO等待拷贝数据; 真正的IO的过程就是拷贝的过程。比如等待鱼上钩的时候也算是钓鱼(adj),当把鱼拿上来的时候也…

【Spring篇】代理模式

🍓个人主页:个人主页 🍒系列专栏:SSM框架 目录 一、场景模拟 二、提出问题 三、代理模式 1.静态代理 2.动态代理 一、场景模拟 ①声明接口 声明计算器接口Calculator,包含加减乘除的抽象方法 public interface…

hadoop基础搭建(hadoop+hive+hbase+zk)(一)

文章目录一、基础环境&插件安装(root)二、创建启动脚本,后续使用三、安装JDK(root)四、安装Hadoop五、安装 rsync(root)六、网络配置(4台服务器,root)七、…

使用html2canvas,将页面转换成图片的采坑记录(Web/Taro h5)

使用html2canvas将页面转换成图片的采坑记录 "html2canvas": "^1.4.1","tarojs/taro": "3.4.0-beta.0"问题: 1. 生成的图片很模糊 2. 生成的图片是空白 3. 生成的图片不完整 截图前是这样 截图后这样 截图后的图片图片缺省了一部分…

【消息中间件】1小时快速上手RabbitMQ

前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:深入、全面、系统的介绍消息中间件 🌰 文章简介:本文将介绍RabbitMQ,一小时快速上…

Good Bye 2022: 2023 is NEAR D. Koxia and Game

原题链接:Problem - D - Codeforces 题面: 大概意思就是给你一个数组a和数组b,你自己设计一个数组c,Koxia可以从a[i]、b[i]和c[i]中选一个,而Mahiru只能从另外两个里选一个,问你有多少个数组c一定能使Mah…

给GitHub装扮个性化首页

我的主页 如何配置 需要创建一个仓库,仓库名要跟GitHub的用户名一样,我的已经创建过了 喜欢我的主页可以直接fork然后在自己的仓库修改,如果想自己装扮直接看下一步 地址:https://github.com/linweiqian 开始装扮 下面展示仓库状态统计的设…

工业控制系统安全控制应用缩略语汇总

声明 本文是学习GB-T 32919-2016 信息安全技术 工业控制系统安全控制应用指南. 下载地址 http://github5.com/view/585而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 工业控制系统安全控制应用缩略语 ICS 工业控制系统(Industrial Contro…

线程的高效利用——线程池

文章目录线程的开销线程池的工作方式ThreadPoolExecutor基础线程池结果的处理线程的开销 线程作为一种昂贵的资源,开销包括如下几点: 1、线程的创建与启动的开销。 2、线程的销毁的开销。 3、线程调度的开销。线程的调度会产生上下文切换,从…

skywalking解析-入门

前几天从github上看最近比较火的项目,发现了skywalking,就进行了些了解,发现这个领域自己目前知之甚少,打算通过对源码的分析深入了解一下分布式追踪。首先从对skywalking介绍开始。 目录一、简介二、整体架构三、源码下载四、系统…

spark-RDD学习笔记

本文是19年学生时学习林子雨老师课程中的一些学习笔记,主要内容包括RDD的概念和运行原理,rdd相关编程api接口以及对应的实例。关于RDD的内容,这个笔记描述的2019年年底之前的pyspark版本,2023年年初时在pyspark的实际工作中rdd已经很少用或者…

【Kafka】Kafka概述

一、闲话 这是2023年的第一篇博客,祝大家在新的一年里一帆风顺,身体健康 二、基本要点 1、Kafka概述 Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要用于大数据实时处理领域 2、消息队列的好处 解耦:…

CAS原理、实践、缺陷分析及优化

文章目录CAS介绍CAS在Java中的底层实现Java源码中使用举例自己实际运用乐观锁举例简单的CAS操作ABA问题及优化实践缺陷及优化只能保证单个变量操作原子性当比较失败后,通常需要不断重试,浪费CPUCAS介绍 CAS(Compare And swap),比较并交换,是一种乐观锁.它是解决多线程并行情况…

【力扣Java】第一个出现两次的字母(HashSet与<<左移)

目录 题目描述 思路与算法 方法一&#xff1a;哈希表 HashSet说明 解题代码 方法二&#xff1a;位运算 左移运算符&#xff08;<<&#xff09; 右移运算符&#xff08;>>&#xff09; 解题代码 题目描述 给你一个由小写英文字母组成的字符串 s &#xff…

事务四大特性

没有开启事务的话直接提交、修改数据&#xff0c;有事务则进行两阶段提交&#xff1a; ①原子性 undolog 来实现一旦失败就马上触发回滚 当前事务是不可再分的&#xff0c;要么一起执行&#xff0c;要么都不执行。 start transaction redolog日志池存储undolog日志&#xff…

【Android OpenCV】Visual Studio 创建支持 OpenCV 库的 CMake 工程 ④ ( OpenCV 官方代码示例 )

文章目录一、OpenCV 官方代码示例1、Windows 平台代码示例2、Android 平台代码示例参考 【Android OpenCV】Visual Studio 创建支持 OpenCV 库的 CMake 工程 ① ( 下载 OpenCV 库 | Windows 中安装 OpenCV 库 ) 博客 , 可下载 OpenCV 库 ; CSDN 下载地址 : https://download.c…