java-AutoCloseable合同:写入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被正确关闭(尽管这是不可靠的,因为我确定它不能保证在发生错误后会成功).

因此,问题基本上是XML是有效的,尽管我们不希望XML无效(因此,不会遗漏错误,因此不会意外处理输出).我正在考虑如何最好地解决这种情况-从close()中删除结束标签写入-这将需要大量的分析重新测试-或只是不使用try-with-resource来控制是否调用它.

但是我有一个普遍的问题是:
当系统提示您close()时,AutoCloseable合同是否仍允许写入您的资源中?我一直在阅读javadoc,但实际上并没有明确禁止它.我想念什么吗?

最佳答案
Java Standard类库中有一些示例,其中close()方法必须执行写操作.这样的示例是DeflaterOutputStream,其javadoc声明:

Writes remaining compressed data to the output stream and closes the underlying stream.

关键是压缩流的最后一位只有在您知道流已关闭时才可以.冲洗不足.

因此,将其与@Kayaman结合使用,有明确的证据表明在close()期间允许流执行写操作.

(另一个示例是BufferedOutputStream,如果需要的话,close()等效于flush()调用.)

转载注明原文:java-AutoCloseable合同:写入close()中允许的资源? - 代码日志