使用完流和读写器后,需要正确关闭它们。这可以通过调用 close() 方法来实现。不过这需要花点心思。请看这段代码:
// 输入流
InputStream input = new FileInputStream("C:\\Users\\Administrator\\Desktop\\input.txt");
int data = input.read();
while(data != -1) {
// 对数据进行一些处理...
doSomethingWithData(data);
data = input.read();
}
input.close(); // 关闭流这段代码乍一看没什么问题。但如果在 doSomethingWithData() 方法中出现异常会怎样呢?没错!InputStream 永远不会关闭!
为了避免这种情况,你可以将代码重写成这样:
InputStream input = null;
try {
input = new FileInputStream("C:\\Users\\Administrator\\Desktop\\input.txt");
int data = input.read();
while(data != -1) {
// 对数据进行一些处理...
doSomethingWithData(data);
data = input.read();
}
} catch(IOException e) {
// 对异常...比如记录日志,或者再次抛出等。
} finally {
if(input != null) {
input.close();
}
}请注意 InputStream 现在是如何在 finally 子句中关闭的。无论 try 块中发生了什么,finally 子句都会被执行。因此,InputStream 将始终关闭。
但是,如果 close() 抛出异常会怎样?比如说流已经关闭了?那么,要捕获这种情况,就必须把对 close() 的调用也包在 try-catch 块中,就像这样:
try {
//...
} catch(IOException e) {
//...
} finally {
try{
if(input != null) {
input.close();
}
} catch(IOException e){
// 做点什么,或者忽略
}
}正确处理 InputStream(或 OutputStream)迭代的代码可能会很难看,正如你所看到的,一旦你也正确处理了异常,就会很难看。这种丑陋的异常处理代码遍布整个代码,反复出现,并不是一件好事。如果有人急于求成,跳过异常处理怎么办?
此外,假设 doSomethingWithData() 首先抛出了一个异常。第一个 catch 子句将捕获该异常,然后 finally 子句将尝试关闭 InputStream。但是,如果 input.close() 方法也抛出异常,会发生什么情况?这两个异常中的哪一个应该在调用栈中向上传播?
幸运的是,有一种方法可以解决这个问题。这个办法叫做 “异常处理模板”。创建一个异常处理模板,在使用后正确关闭数据流。该模板只需编写一次,并在整个代码中重复使用。简单易用。要了解更多信息,请访问 Java 中的异常处理模板。
从 Java 7 开始,Java 包含了一种新的异常处理机制,称为 “try with resources”。这种异常处理机制特别针对在使用需要在使用后正确关闭的资源(如 InputStream、OutputStream 等)时的异常处理。
一个简单示例:
package com.hxstrive.java_io.demo01;
import java.io.FileReader;
import java.io.Reader;
/**
* FileReader 示例
* @author hxstrive.com
*/
public class FileReaderDemo {
public static void main(String[] args) {
// try with resources
try(Reader reader = new FileReader("C:\\Users\\Administrator\\Desktop\\input.txt")) {
int data = reader.read();
while(data != -1){
char dataChar = (char) data;
System.out.print(dataChar);
data = reader.read();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}上述代码,当代码正常或异常退出 try-catch 后,JVM 会自动关闭 Reader 资源。