假设我想创建JSON并使用Java JSON Streaming API将其存储在String中。为此,我在其顶部创建了ByteArrayOutputStream(BAOS)和JsonGenerator。

ByteArrayOutputStream collector = new ByteArrayOutputStream();
JsonGenerator jsonGenerator = Json.createGenerator(collector);


过了一会儿,当我用完它之后,我从BAOS那里拿了String并打算释放所有资源。从BAOS关闭方法实现如下

public void close() throws IOException {
}


它什么也没做。但是,JsonGenerator的close方法不仅关闭基础流,而且还刷新缓冲区并回收缓冲池(坦白地说,我不知道后者的含义)。
我怀疑JsonGenerator在将数据写入BAOS时会缓冲数据。但是,我需要花费一些时间来进一步调查,所以我希望有人已经知道:关闭发电机是否有意义,或者没有。
注意
我使用javax.json的Glassfish实现。

最佳答案

好。我检查了JsonGeneratorImpl源代码。我不得不说我真的需要关闭它。首先,JsonGeneratorImpl在这里从BufferPoolImpl接收缓冲区:

public final char[] take() {
    char[] t = (char[])getQueue().poll();
    if (t == null)
        return new char[4096];
    return t;
}


当我们调用close时,我们将其放回原处:

public final void recycle(char[] t)
{
    getQueue().offer(t);
}


如果像我所讨论的那样创建jsonGenerator,这没有多大意义:

JsonGenerator jsonGenerator = Json.createGenerator(collector);


因为在这种情况下,每个新创建的生成器都将使用其自己的JsonProvider实例和自己的缓冲池实例,当我完成对生成器的使用时,它们将由GC收集。因此最好创建JsonGeneratorFactory,因为此工厂创建的所有生成器将共享公共缓冲池。是的-在这种情况下,最好最后关闭发电机。
关闭生成器的另一个原因是close方法调用flushBuffer方法。是的,无论输出流的类型如何,生成器都会使用缓冲区:

void writeChar(char c) {
    if (this.len >= this.buf.length) {
        flushBuffer();
    }
    this.buf[(this.len++)] = c;
}


因此,最终答案是肯定的。最后关闭JsonGenerator总是有意义的。
更新
正如@StephenC正确指出的那样,有另一个原因可以将其关闭,因为它强制检查未完成的JSON:

if ((this.currentContext.scope != Scope.IN_NONE) || (this.currentContext.first)) {
  throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
}

关于java - 如果它是在ByteArrayOutputStream之上创建的,关闭JsonGenerator是否有意义?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28628057/

10-10 15:13