9

事实证明,几乎没有人正确关闭 Java 中的资源。程序员要么根本不使用try-finally块,要么只是放入resource.close()也不finally正确的块(因为Throwable来自try 块的close()阴影)。Throwable有时他们把 with 之类的东西IOUtils.closeQuietly()只对 for InputStream,而不是 for OutputStreamtry-with-resources解决了所有这些问题,但仍有大量项目是用 Java 6 编写的。

try-with-resources在 Java 6中模拟的最佳方法是什么?现在我使用Guava Closer,它比没有好,但仍然比try-with-resources. 此外,还有一种称为贷款模式的模式,但 Java 中缺少 lambda 使得这种模式非常麻烦。有没有更好的办法?

4

3 回答 3

3

我找到了一个很好的替代品try-with-resources。它使用带有注释处理的Lombok库:

 @Cleanup InputStream in = new FileInputStream(args[0]);
 @Cleanup OutputStream out = new FileOutputStream(args[1]);
 byte[] b = new byte[10000];
 while (true) {
   int r = in.read(b);
   if (r == -1) break;
   out.write(b, 0, r);
 }

但是,它不能正确处理异常。此错误已超过 1 年,仍未关闭:https ://code.google.com/p/projectlombok/issues/detail?id=384

于 2013-10-24T11:50:08.147 回答
0

虽然匿名类很冗长,但在 java 领域还是可以接受的

    new TryWithResource<InputStream>(){
        protected InputStream init() throws Exception {
            return new FileInputStream("abc.txt");
        }
        protected void use(InputStream input) throws Exception{
            input.read();
        }
    };

----

abstract class TryWithResource<R>
{
    abstract protected R init() throws Exception;
    abstract protected void use(R resource) throws Exception;

    // caution: invoking virtual methods in constructor!
    TryWithResource() throws Exception
    {
        // ... code before
        R r = init();
        use(r);
        // ... code after
    }
}
于 2013-10-21T15:04:41.350 回答
0

如果您唯一的问题IOUtils.closeQuietly是它忽略了 OutputStreams 上的异常,那么您可以简单地调用close()它们,或者创建您自己的实用程序类来自动区别对待这两者,如下所示:

public static void close(Closeable resource)
{
    try
    {
        resource.close();
    }
    catch(Exception e)
    {
        //swallow exception
    }
}

public static void close(OutputStream o)
{
    //throw any exceptions
    o.close();
}

在所有常见情况下,将在编译时选择正确的重载方法,尽管如果您将OutputStreams 作为Closeables 传递,那么您必须更改它以进行动态instanceof检查以确保OutputStreams 总是抛出异常。

于 2013-10-21T15:07:48.503 回答