目录:系统学习 Java IO---- 目录,概览

我们使用流后,需要正确关闭 Streams 和 Readers / Writers 。

这是通过调用 close() 方法完成的,看看下面这段代码:

InputStream input = new FileInputStream("D:\\out.txt");

int data = input.read();
while(data != -1) {
//do something with data...
doSomethingWithData(data);
data = input.read();
}
input.close();

这段代码乍一看似乎没问题。

但是如果从 doSomethingWithData() 方法内部抛出异常会发生什么?

对!input.close(); 将得不到执行的机会,InputStream 永远不会关闭!

为避免这种情况,可以把关闭流的代码放在 finally 块里面确保一定被执行,将代码重写为:

InputStream input = null;

try{
input = new FileInputStream("D:\\out.txt"); int data = input.read();
while(data != -1) {
//do something with data...
doSomethingWithData(data);
data = input.read();
}
}catch(IOException e){
//do something with e... log
} finally {
if(input != null) input.close();
}

但是如果 close() 方法本身抛出异常会发生什么? 这样流会被关闭吗?

好吧,要捕获这种情况,你必须在 try-catch 块中包含对 close() 的调用,如下所示:

} finally {
try{
if(input != null) input.close();
} catch(IOException e){
//do something, or ignore.
}
}

这样确实可以解决问题,就是太啰嗦太难看了。

有一种方法可以解决这个问题。就是把这些重复代码抽出来定义一个方法,这些解决方案称为“异常处理模板”。

创建一个异常处理模板,在使用后正确关闭流。此模板只编写一次,并在整个代码中重复使用,但感觉还是挺麻烦的,就不展开讲了。

还好,从 Java 7 开始,我们可以使用名为 try-with-resources 的构造,

// 直接在 try 的小括号里面打开流
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
} }

当try块完成时,FileInputStream 将自动关闭,换句话说,只要线程已经执行出try代码块,inputstream 就会被关闭。

因为 FileInputStream 实现了 Java 接口 java.lang.AutoCloseable ,

实现此接口的所有类都可以在 try-with-resources 构造中使用。

public interface AutoCloseable {
void close() throws Exception;
}

FileInputStream 重写了这个 close() 方法,查看源码可以看到其底层是调用 native 方法进行操作的。

try-with-resources构造不仅适用于Java的内置类。

还可以在自己的类中实现 java.lang.AutoCloseable 接口,

并将它们与 try-with-resources 构造一起使用,如:

public class MyAutoClosable implements AutoCloseable {
public void doIt() {
System.out.println("MyAutoClosable doing it!");
}
@Override
public void close() throws Exception {
System.out.println("MyAutoClosable closed!");
} }
private static void myAutoClosable() throws Exception {
try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
myAutoClosable.doIt();
}
}
// 将会输出:
// MyAutoClosable doing it!
// MyAutoClosable closed!

try-with-resources 是一种非常强大的方法,可以确保 try-catch 块中使用的资源正确关闭,

无论这些资源是您自己的创建,还是 Java 的内置组件。

系统学习 Java IO (二)----IO 异常处理的更多相关文章

  1. 系统学习 Java IO (十二)----数据流和对象流

    目录:系统学习 Java IO---- 目录,概览 DataInputStream/DataOutputStream 允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型. 要想使用 ...

  2. 系统学习 Java IO ---- 目录,概览

    Java IO 类的系统教程,原创.主要参考自英文教程 Java IO Tutorial 和 Java Doc. http://tutorials.jenkov.com/java-io/index.h ...

  3. 系统学习 Java IO (十三)----字符读写 Reader/Writer 及其常用子类

    目录:系统学习 Java IO---- 目录,概览 Reader Reader 类是 Java IO API 中所有 Reader 子类的基类. Reader 类似于 InputStream ,除了它 ...

  4. 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile

    目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...

  5. 系统学习 Java IO (一)----输入流和输出流 InputStream/OutputStream

    目录:系统学习 Java IO ---- 目录,概览 InputStream 是Java IO API中所有输入流的父类. 表示有序的字节流,换句话说,可以将 InputStream 中的数据作为有序 ...

  6. 系统学习 Java IO (十六)----这么多类,应该用哪个?

    目录:系统学习 Java IO---- 目录,概览 Java IO目的和功能 Java IO 包含 InputStream,OutputStream,Reader 和 Writer 类的许多子类. 原 ...

  7. 系统学习 Java IO (十四)----字符读写缓存和回退 BufferedReader/BufferedWriter & PushbackReader

    目录:系统学习 Java IO---- 目录,概览 BufferedReader BufferedReader 类构造器接收一个 Reader 对象,为 Reader 实例提供缓冲. 缓冲可以加快 I ...

  8. 系统学习 Java IO (九)----缓冲流 BufferedInputStream/BufferedOutputStream

    目录:系统学习 Java IO---- 目录,概览 BufferedInputStream BufferedInputStream 类为输入流提供缓冲. 缓冲可以加快IO的速度. BufferedIn ...

  9. 系统学习 Java IO (六)----管道流 PipedInputStream/PipedOutputStream

    目录:系统学习 Java IO---- 目录,概览 PipedInputStream 类使得可以作为字节流读取管道的内容. 管道是同一 JVM 内的线程之间的通信通道. 使用两个已连接的管道流时,要为 ...

随机推荐

  1. wpf控件设计时支持(1)

    原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开发环境下,右侧的Proper ...

  2. 1 WCF 一个基础理论 以及如何实现一个简单wcf服务

    1 SOA : service oriented architecture 面向服务的架构 2 web service标准 3 概念理解图 4 WCF类库 项目的 wcf简单实现 首先创建一个简单的w ...

  3. MySQL SYS CPU高的案例分析(一)

    原文:MySQL SYS CPU高的案例分析(一) [现象] 最近关注MySQL CPU告警的问题时,发现有一种场景,有一些服务器最近都较频繁的出现CPU告警,其中的现象是 SYS CPU占比较高. ...

  4. 《菊与刀》original 的阅读

    0. 词汇 foe:敌人,反对者,危害物: rigid:严格的,僵硬的,死板的, they are incomparably rigid in their behavior, innovation:革 ...

  5. Android sendToTarget

    在使用message进行handler的数据交互的时候不可避免的会使用到message作为数据的载体,可是在使用message的时候有人会直接new一个message,有人会使用handler.obt ...

  6. JDBC学习笔记——增删改查

    1.数据库准备  要用JDBC操作数据库,第一步当然是建立数据表: ? 1 2 3 4 5 6 CREATE TABLE `user` (   `id` int(11) NOT NULL AUTO_I ...

  7. windows添加本地文件托管到新增github库

    新增repositoy.登录gitHub,并点击“New Reposoitory” 写入名字  之后点击“create resposity” \ 按照上图中的步骤可以完成.以下为完成步骤. 2. 在本 ...

  8. C#异步委托等待句柄的使用

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. main()如果返回0,则代表程序正常退出,返回非零代表程序异常退出。

    读到这里,大家应该了解了main函数返回值的来龙去脉了.下面介绍一下main函数返回值的作用以及如何获得这个返回值.main函数的返回值用于说明程序的退出状态.如果返回0,则代表程序正常退出.返回其它 ...

  10. Hutool 3.0.8 发布,Java 工具集

    Hutool 是一个Java工具包,提供了丰富的文件.日期.日志.正则.字符串.配置文件等工具方法,并封装了一套简单易用的ORM框架. 主页:http://hutool.cn/ 文档:http://h ...