通常,在处理Java IO代码时,这就是我写的
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
// I put the close code in finally block, to enture the opened
// file stream is always closed even there is exception happened.
if (out != null) {
// Another try catch block, troublesome.
try {
out.close();
} catch (IOException ex) {
}
}
}
正如您所看到的,当我尝试关闭文件流时,我需要处理另一个try ... catch块。
看起来很麻烦:(
有什么办法可以避免吗?将close代码放在非finally块中我感觉不舒服,因为其他代码引起的异常将无法调用“close”。
答案 0 :(得分:13)
最后关闭流是非常重要的。您可以使用实用程序方法简化此过程,例如:
public static void closeStream(Closeable closeable) {
if(null != closeable) {
try {
closeable.close();
} catch(IOException ex) {
LOG.warning("Failed to properly close closeable.", ex);
}
}
}
我认为至少记录一个流关闭失败。然后用法变为:
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
closeStream(out);
}
在Java 7中,我认为流将自动关闭,并且对这些块的需求应该是多余的。
答案 1 :(得分:6)
Automatic Resource Management,它将自动提供对此的处理。在此之前,OutputStream
,InputStream
等对象实现了自Java 5以来的Closeable
接口。我建议您提供一种实用方法来安全地关闭它们。这些方法通常会占用异常,因此请确保只在想要忽略异常时使用它们(例如在finally方法中)。例如:
public class IOUtils {
public static void safeClose(Closeable c) {
try {
if (c != null)
c.close();
} catch (IOException e) {
}
}
}
请注意,close()
方法可以多次调用,如果它已经关闭,后续调用将无效,因此在try块的正常操作期间提供关闭调用,其中异常不会被忽略了。 From the Closeable.close documentation:
如果流已经关闭,则调用此方法无效
因此关闭代码的常规流中的输出流,safeClose
方法只会在try块中出现故障时执行close:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
//...
out.close();
out = null;
} finally {
IOUtils.safeClose(out);
}
答案 2 :(得分:4)
讨论
Try-catch-finally and then again a try catch
和
Is there a preference for nested try/catch blocks?
基本上,问题是close()
例外是否值得捕捉。
答案 3 :(得分:3)
Project Lombok提供了一个@Cleanup注释,它不再需要try catch块。 Here's an example
答案 4 :(得分:1)
我倾向于使用效用函数:
public static void safeClose(OutputStream out) {
try {
out.close();
} catch (Exception e) {
// do nothing
}
}
将代码更改为更适合:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
// do stuff
} catch (Exception e) {
// do something
} finally {
safeClose(out);
}
至少在Java 7(希望)ARM ("Automatic Resource Management") blocks会有所帮助之前,你无法在Java中做得更好。
答案 5 :(得分:1)
编写一个类似于下面的方法;来自你最后一块的电话......
static void wrappedClose(OutputStream os) {
if (os != null) {
try {
os.close();
}
catch (IOException ex) {
// perhaps log something here?
}
}
答案 6 :(得分:0)
分开你的try / catch和try / finally块。
try
{
FileOutputStream out = new FileOutputStream("myfile.txt");
try
{
// More and more code goes here...
}
finally
{
out.close();
}
}
catch (Exception e)
{
//handle all exceptions
}
外部捕获物也将捕获关闭时抛出的任何东西。