假设您需要打开的不是一个文件,而是两个文件。你会做的
final InputStream in = new FileInputStream(file1);
final OutputStream out = new FileOutputStream(file2);
try {
// ...
} finally {
out.close();
in.close();
}
如果out 无法打开,你会得到一个异常,因为它在try 块之外,in 不会在finally 块中关闭。
另一种方法:
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file1);
out = new FileOutputStream(file2);
// ...
} finally {
if (out != null) out.close();
if (in != null) in.close();
}
如果out 无法打开,您将转到finally 块并关闭两个流。如果in打开失败,你会去finally块,只释放in——因为out==null。
编辑
正如 aetheria 所提到的,该代码不起作用,因为 close() 在 Java 中引发异常。它可以通过将每个资源发布放在它自己的try-catch 块中来轻松修复:
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file1);
out = new FileOutputStream(file2);
// ...
} finally {
try{ out.close(); }catch(Exception e){}
try{ in.close(); }catch(Exception e){}
}
我放弃了 null 检查 - 如果 in 或 out 为 null,它将抛出一个 NullPointerException 将被忽略。我忽略close 异常的原因是处理方法首先不应该抛出异常。如果需要处理关闭异常,您可以随时再次关闭流,在 finally 块之后。这样,可以关闭的任何流都将已经关闭(因此您不必担心),并且您可以更优雅地处理来自close 的任何异常。
现在,aetheria 还建议为每个资源放置一个单独的 try-finally 块,如下所示:
final InputStream in = new FileInputStream(file1);
try {
final OutputStream out = new FileOutputStream(file2);
try {
// ...
} finally {
out.close();
}
} finally {
in.close();
}
这可行,但即使只有两个资源,它也不太优雅,因为它会拆分分配和释放代码,使得跟踪它变得更加困难(至少在我看来)。