【问题标题】:Access StringWriter contents as stream以流形式访问 StringWriter 内容
【发布时间】:2018-10-26 14:45:30
【问题描述】:

我想从存储在我的 MongoDB 中的几个较小的文档中将一个大型文档编译为 JSON。我编写了一个 Java 函数来编译我的文档,现在我希望我的应用程序能够访问 JSON,以便将其返回给客户端,或者对其进行进一步处理。

我的问题是实例化 JSON 字符串会占用大量内存,因此我开始遇到 OutOfMemoryErrors。我已经从 MongoDB 库中实现了自己的 toJSON 方法版本,如下所示:

/**
 * Borrowed from the MongoDB toJSON method for Documents, except we dont instantiate the json string and return the writer instead.
 *
 * @return a buffer containing the JSON representation of the given document
 * @throws org.bson.codecs.configuration.CodecConfigurationException if the registry does not contain a codec for the document values.
 */
private Writer toJson(Document document) {
        JsonWriter writer = new JsonWriter(new StringWriter(), new JsonWriterSettings(true));
        new DocumentCodec().encode(writer, document, EncoderContext.builder().isEncodingCollectibleDocument(true).build());
        return writer.getWriter();
}

此方法不返回字符串,而是返回缓冲了 JSON 字符串的写入器。现在我想在我的应用程序中使用它而不调用 toString() 方法,就像我在许多在线示例中看到的那样。我找到的最接近的例子是解决方案at the bottom of this page

try (BufferedWriter bw = new BufferedWriter(new FileWriter("TempFile1mod"))) {
    final int aLength = aSB.length();
    final int aChunk = 1024;// 1 kb buffer to read data from 
    final char[] aChars = new char[aChunk];

    for (int aPosStart = 0; aPosStart < aLength; aPosStart += aChunk) {
    final int aPosEnd = Math.min(aPosStart + aChunk, aLength);
    aSB.getChars(aPosStart, aPosEnd, aChars, 0); // Create no new buffer
    bw.write(aChars, 0, aPosEnd - aPosStart);// This is faster than just copying one byte at the time
    }

这确实可以满足我的要求,并且可以让我将字符串分块写入任何流。但是,由于在我看来这似乎是一个常见的用例,我本来希望 Java 有一些通用的方法来将我的数据从字符串缓冲区传递到另一个流中。

我错过了什么吗?

【问题讨论】:

  • 嗯,像 Apache Commons IO 这样的库可以提供类似的实用方法。

标签: java json string stream buffer


【解决方案1】:

感谢@Thomas 的建议。我最终将我的 StringBuffer 传递给CharSequenceInputStream,如下所示:

/**
 * Borrowed from the MongoDB toJSON method for Documents, except we dont
 * instantiate the JSON String but return an InputStream instead.
 *
 * @return a buffer containing the JSON representation of the given document
 * @throws org.bson.codecs.configuration.CodecConfigurationException if the
 *         registry does not contain a codec for the document values.
 */
private InputStream toJson(Document document) {
    JsonWriter writer = new JsonWriter(new StringWriter(), new JsonWriterSettings(true));

    new DocumentCodec().encode(writer, document,
            EncoderContext.builder().isEncodingCollectibleDocument(true).build());

    CharSequence result = ((StringWriter) writer.getWriter()).getBuffer();

    return new CharSequenceInputStream(result, Charset.forName("UTF-8"));
}

【讨论】:

    猜你喜欢
    • 2016-01-05
    • 2020-01-23
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多