我是否需要同时调用 .dispose() (javax.jcr.Binary) 和 .close() (java.io.InputStream)?

Do I need to call both .dispose() (javax.jcr.Binary) and .close() (java.io.InputStream)?

我是否需要单独定义 Binary 对象以便我可以在其上调用 .dispose();(参见 methodOne()),或者是否会在自动关闭 InputStream 时自动处理(参见 methodTwo())?

private void methodOne(Resource resource) {
    Binary binary = resource.getValueMap().get("jcr:data", Binary.class);
    try {
        InputStream is = null;
        try {
            is = binary.getStream();
            // ...do something with the InputStream...
        } catch (RepositoryException e) {
            LOG.error("RepositoryException trying to get an InputStream from the resource.");
        } finally {
            if (is != null) {
                IOUtils.closeQuietly(is);
            }
        }
    } finally {
        binary.dispose();
    }
}

private void methodTwo(Resource resource) {
    try (InputStream is = resource.getValueMap().get("jcr:data", Binary.class).getStream()) {
        // ...do something with the InputStream...
    } catch (IOException e) {
        LOG.error("IOException from trying to auto-close InputStream.");
    } catch (RepositoryException e) {
        LOG.error("RepositoryException trying to get an InputStream from the resource.");
    }
}

我真的很困惑如何测试 methodTwo 中的匿名二进制资源是否被正确处理,这就是为什么我什至首先问这个问题。

除非 class 您从关闭流的文档中获取流就足够了,否则您需要确保在 try 中列出其他可关闭的资源以获取 try-with-resources 为您关闭它们。

您说过 Binary 没有实现 AutoCloseable。刺激性。 :-) 你总是可以定义一个包装器(因为我认为这不是你需要处理的唯一地方),沿着这些线:

public class ACBinaryWrapper implements AutoCloseable {
    private Binary binary;

    public ACBinaryWrapper(Binary binary) {
        this.binary = binary;
    }

    public Binary getBinary() {
        return this.binary;
    }

    public void close() { 
        if (this.binary != null) {
            Binary b = this.binary;
            this.binary = null;
            b.dispose();
        }
    }
}

然后:

private void yourMethod(Resource resource) {
    try (
        ACBinaryWrapper acbinary = new ACBinaryWrapper(
            resource.getValueMap().get("jcr:data", Binary.class)
        );
        InputStream is = acbinary.getBinary().getStream();
    ) {
        // ...do something with the InputStream...
    } catch (IOException e) {
        // ...appropriate handling...
    } catch (RepositoryException e) {
        // ...appropriate handling...
    }
}

请注意 binary 是如何与 is 分开列出的。


您在 IOException 处理程序中的 LOG 语句等似乎假设唯一可能发生的 I/O 错误是在关闭流时。通常,从流中读取也会导致 I/O 错误。