情景
写代码时发现如果打开了多个stream,那么关闭的时候需要些很多冗余代码。就像下面这样:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "test.txt");
InputStream in = null;
try {
in = new FileInputStream(file);
// operation input stream
// ...
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
// !!!这里如果要关闭的流很多,那么就会写出很多冗余且相似的代码
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}
}
如果打开的流超过10个,那么代码中很多都是上面那样的代码。所以,需要编写方法去统一处理关闭流。
解决
方法1:自行编码实现
可以把这个方法放到工具类中。但是本着不要重复造轮子的想法, 应该有工具类已经实现了这个方法。
private void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
// ignore
}
}
}
方法2:使用commons-io的IOUtils
Maven坐标:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
源代码:
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException ioe) {
// ignore
}
}
调用示例:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "test.txt");
InputStream in = null;
try {
in = new FileInputStream(file);
// operation input stream
// ...
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(in);
}
}
方法3:try-with-resource (JDK1.7+)
在common-io-2.6版本中,这个IOUtils.closeQuietly(arg0);方法已经被弃用了,并且没有替代方案。
@Deprecated的说明如下:As of 2.6 removed without replacement. Please use the try-with-resources statement or handle suppressed exceptions manually.给我们的建议就是使用try-with-resources语句或者手动处理压制的异常。
try-with-resource这个语法糖是JDK1.7开始引入的,具体语法如下:
/**
* auto closeable stream为实现自动关闭的Stream
* JDK1.7 新增了一个java.lang.AutoCloseable接口,接口内部只有close()方法。
* JDK1.7 同时修改了java.io.Closeable接口,这个接口继承了AutoCloseable接口。
* 所以之前那些实现Closeable接口的stream都可以实现AutoCloseable接口中的自动关闭的功能。
*/
try (auto closeable stream) {
} catch (Exception e) {
}
示例:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "test.txt");
try (InputStream in = new FileInputStream(file)) {
// operation input stream
// ...
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// ignore
}
}