使用try-with-resources优雅的关闭IO流
Java类库中包括许多必须通过调用close方法来手工关闭的资源。例如InputStream、OutputStream和java.sql.Connection。客户端经常会忽略资源的关闭,造成严重的性能后果也就可想而知了。根据经验,try-finally 语句是确保资源会被适当关闭的最佳方法,就算是发生异常或者返回也一样:
public String tryfinally(String path) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File(path)));
try{
return reader.readLine();
}finally {
reader.close();
}
}
即便用 try-finally 语句正确地关闭了资源,它也存在着些许不足。因为在try块和finally块中的代码,都会抛出异常。例如,底层的物理设备出现异常,那么调用readLine就会抛出异常,基于同样的原因,调用close也会出现异常。在这种情况下,第二个异常完全抹除了第一个异常。在异常堆栈轨迹中,完全没有关于第一个异常的记录,这在现实的系统中会导致调试变得非常复杂,因为通常需要看到第一个异常的记录,这在现实的系统中会导致调试变得非常复杂,因为通常需要看到第一个异常才能诊断出问题何在。虽然可以通过编写代码来禁止第二个异常,保留第一个异常,但事实上没有人会这么做,因为实现起来太繁琐了。
如何完美解决这种问题呢?当然是Java7中引入的 try-with-resources 语句。
还是上面的这段代码,使用 try-with-resources 语句之后,新的代码如下:
public String tryresources(String path) throws IOException {
try(BufferedReader reader = new BufferedReader(new FileReader(new File(path)))){
return reader.readLine();
}
}
使用这种 try-with-resources 不仅使代码变得简洁易懂,也更容易进行诊断。以上段代码为例,如果调用 readLine 和 不可见的 close 方法都抛出异常,后一个异常就会被禁止,以保留第一个异常。事实上,为了保留你想看到的那个异常,即便多个异常都可以被禁止。这些被禁止的异常并不是简单地被抛弃了,而是会被打印在堆栈轨迹中,并注明它们是被禁止的异常。通过编程调用 getSuppressed 方法还可以访问到它们,getSuppressed 方法也已经添加在Java7的Throwable中了。
使用 try-with-resources 语句有什么要求吗?
是的,要使用这个构造的资源,必须先实现 AutoCloseable 接口,其中包含了单个返回 void 的 close 方法。Java类库与第三方类库中的许多类和接口,现在都实现或扩展了 AutoCloseable 接口。
public interface AutoCloseable {
void close() throws Exception;
}
以下是使用 try-with-resources 的第二个范例:
void tryresources(String src,String dst) throws IOException {
try(InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)){
byte[] bytes = new byte[1024];
int n;
while ((n=in.read(bytes))>=0){
out.write(bytes,0,n);
}
}
}
在 try-with-resources 语句中还可以使用 catch 子句,就像在平时的 try-finally 语句中一样。
public String tryresources(String path){
try(BufferedReader reader = new BufferedReader(new FileReader(new File(path)))){
return reader.readLine();
} catch (IOException e) {
return null;
}
}
有了 try-with-resources 语句,在使用必须关闭的资源时,就能更轻松地正确编写代码了。
使用try-with-resources优雅的关闭IO流的更多相关文章
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...
- Android—Socket中关闭IO流后导致Socket关闭不能再收发数据的解决办法
以Socket发送数据为例: 发送数据时候要声明:DataOutputStream os = new DataOutputStream(socket.getOutputStream()); 最近开发遇 ...
- 分页写入文件,第二次分页前一定要关闭IO流啊。。否则文件写不全。。- -粗心
- JavaSE | IO流
java.io.File类(文件和目录路径名的抽象表示形式) 如果希望在程序中操作文件和目录都可以通过File类来完成,File类能新建.删除.重命名文件和目录. File类是文件或目录的路径,而不是 ...
- JAVA之IO流(字节流)
输入和输出 JAVA的流分为输入流和输出流两部分, 输入流:InputStream或者Reader:从文件中读到程序中: 输出流:OutputStream或者Writer:从程序中输出到文件中: Re ...
- Java IO流
File类 ·java.io.File类:文件和目录路径名的抽象表示形式,与平台无关 ·File能新建.删除.重命名文件和目录,但File不能访问文件内容本身.如果需要访问文件内容本身,则需要使用输入 ...
- RandomAccessFile&IO流&排序&方法论
RandomAccessFile&IO流&排序&方法论 我们总觉得历史是极其遥远的东西,与我们并无关联,又觉得历史隐藏在图书馆的旧书之中. 然而,我们每个人都有真真切切的历史. ...
- IO流简要总结
IO流小总结 IO流的本质就是用于数据的传输,根据流的方向的不同,有输入流.输出流.根据数据类型的不同,又有字节流.字符流. 字节流 字节输入流 InputStream 字节输出流 Outpu ...
- 第十一章 IO流
11.IO流 11.1 java.io.File类的使用 1课时 11.2 IO原理及流的分类 1课时 11.3 节点流(或文件流) 1课时 11.4 缓冲流 1课时 11.5 转换流 1课时 11. ...
随机推荐
- 分布式架构原理解析,Java开发必修课
1. 分布式术语 1.1. 异常 服务器宕机 内存错误.服务器停电等都会导致服务器宕机,此时节点无法正常工作,称为不可用. 服务器宕机会导致节点失去所有内存信息,因此需要将内存信息保存到持久化介质上. ...
- 栈到CLR
提起栈想必会听到这样几个关键词:后进先出,先进后出,入栈,出栈. 栈这种数据结构,数组完全可以代替其功能. 但是存在即是真理,其目的就是避免暴漏不必要的操作. 如角色一样,不同的情景或者角色拥有不同的 ...
- Java进阶篇设计模式之一 ----- 单例模式
前言 在刚学编程没多久就听说过设计模式的大名,不过由于当时还是个彻彻底底的菜鸟,并没有去触碰.直到在开始工作中对简单的业务代码较为熟悉之后,才正式的接触设计模式.当时最早接触的设计模式是工厂模式,不过 ...
- Java进阶篇设计模式之二 ----- 工厂模式
前言 在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法.本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式.工厂方法和抽象工厂模式. 简单工厂模式 简单工厂模式是属于创建型模 ...
- Vue不能检测数组或对象变动问题的解决
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python:鲜为人知的功能特性(上)
GitHub 上有一个名为<What the f*ck Python!>的项目,这个有趣的项目意在收集 Python 中那些难以理解和反人类直觉的例子以及鲜为人知的功能特性,并尝试讨论这些 ...
- 网站HTTP升级HTTPS完全配置手册
本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 今天,所有使用Google Chrome稳定版的用户迎来了v68正式 ...
- 补习系列(13)-springboot redis 与发布订阅
目录 一.订阅发布 常见应用 二.Redis 与订阅发布 三.SpringBoot 与订阅发布 A. 消息模型 B. 序列化 C. 发布消息 D. 接收消息 小结 一.订阅发布 订阅发布是一种常见的设 ...
- 基于 DataLakeAnalytics 做跨地域的数据分析
在阿里云上,很多客户的应用都是多地域部署的, 比如在北京(cn-beijing)的地域部署一个应用让北方的客户访问快一点,同时在杭州(cn-hangzhou)地域部署一份让南方的客户访问快一点.多地域 ...
- SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...