繁体   English   中英

AutoCloseable contract:写入close()允许的资源?

[英]AutoCloseable contract: writing to resource allowed in close()?

我偶然发现了内部的以下构造:

class OurXmlWriter implements AutoCloseable {
    private XMLStreamWriter streamWriter;
    public OurXmlWriter(OutputStream stream) {
        streamWriter = XMLOutputFactory.newInstance()
                        .createXMLStreamWriter(outputStream, "UTF-8");
    }

    @Override
    public void close() {
        try {
            // is this allowed?
            streamWriter.writeEndDocument();
        } catch (XMLStreamException e) {
            throw new RuntimeException();
        } finally {
            try {
                streamWriter.close();
            } catch (XMLStreamException e) {
                throw new RuntimeException();
            }
            streamWriter = null;
        }
    }
}

我们遇到的问题是:

try (OurXmlWriter writer = new OurXmlWriter(new FileOutputStream("output.xml"))) {
    writer.writeStartTag();
    // write some data elements correctly
    throw new OutOfMemoryError(); // that's not done explicitly but happens
}

这仍然调用close() - 这样就可以了,但是会导致xml正确关闭(虽然不可靠,因为我确信它不能保证在Error后成功)。

所以问题基本上是XML是有效的,尽管我们不喜欢它(因此在错过错误的情况下不会意外地处理输出)。 我正在思考如何最好地处理这种情况 - 从close()删除结束标记 - 这需要大量的分析重新测试 - 或者只是不使用try-with-resource来控制它是否被调用。

但我的一般问题是:当你被告知close()时, AutoCloseable合约是否允许仍然写入你的资源? 我一直在阅读javadoc,但它并没有真正明确禁止它。 我错过了什么吗?

基本上Javadoc中没有任何东西表明它不会被允许,事实上它说的是

请注意,与close的方法java.io.Closeableclose 不需要方法为幂等。 换句话说,不止一次调用此close方法可能会产生一些可见的副作用,这与Closeable.close不同,如果多次调用则需要它无效。

这允许副作用,甚至不要求该方法是幂等的。 考虑到写文档的结尾是一个相对不令人惊讶的副作用,我会说没关系。 但当然只是因为它不被禁止并不意味着它是允许的,YMMV,基于意见,咨询你的内部规则手册等。

Java Standard类库中有一些示例,其中close()方法必须执行写操作。 一个这样的例子是DeflaterOutputStream它的javadoc状态:

将剩余的压缩数据写入输出流并关闭基础流。

关键是压缩流的最后一位只能在您知道流被关闭时才会出现。 冲洗是不够的。

因此将它与@Kayaman结合使用,并且有明确证据表明允许流在close()期间执行写入。

(另一个例子是BufferedOutputStream ,其中close()在需要时执行相当于flush()调用。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM