1、为什么需要模板来关闭IO流?
InputStream input = null;
try{
input = new FileInputStream("c:\\data\\input-text.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, perhaps rethrow etc.
} finally {
if(input != null)
input.close();
}
- 如果没有一定的规则,有的程序员会忘记关闭流
- 某个异常最先从doSomethingWithData方法内抛出。第一个catch会捕获到异常,然后在finally里程序会尝试关闭InputStream。但是如果还有异常从close()方法内抛出呢?这两个异常中得哪个异常应当往调用栈上传播呢?
2、模板
- 预设两个变量,input和processException ,分别代表输入流和处理过程中的异常
- 在catch块中捕获IOException异常,并将其引用赋值给processException
- 在finally块中进行流关闭:
- 首先判断input流是否为空,如果不为空且关闭IO流出错的话,分两种情况
- processException 不为空,那么在抛出的错误中,传入processException和关闭IO流操作出现的错误(就是两个错误都抛出)
- processException 为空,那么在抛出的错误中,传入关闭IO流操作出现的错误(只有IO流关闭时出错,那么只传一个)
- 如果input为空,那就是没有开启IO流,不用关闭流了。判断一下processException是否为空,不为空的报错一下就行了。
Input input = null;
IOException processException = null;
try{
input = new FileInputStream(fileName);
//...process input stream...
} catch (IOException e) {
processException = e;
} finally {
if(input != null){
try {
input.close();
} catch(IOException e){
if(processException != null){
throw new MyException(processException, e,
"Error message..." +
fileName);
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName;
}
}
}
if(processException != null){
throw new MyException(processException,
"Error processing InputStream for file " +
fileName;
}