将 StringWriter 内容作为流访问
Access StringWriter contents as stream
我想从存储在我的 MongoDB 中的几个小文档编译一个大文档 JSON。我已经编写了一个 Java 函数来编译我的文档,现在我希望我的应用程序能够访问 JSON 以便 return 它到客户端,或者做进一步的对其进行处理。
我的问题是实例化 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();
}
不是 return 字符串,此方法 return 是 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 有一些通用的方法将我的数据从字符串缓冲区传输到另一个流中。
我是不是漏掉了什么?
感谢@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"));
}
我想从存储在我的 MongoDB 中的几个小文档编译一个大文档 JSON。我已经编写了一个 Java 函数来编译我的文档,现在我希望我的应用程序能够访问 JSON 以便 return 它到客户端,或者做进一步的对其进行处理。
我的问题是实例化 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();
}
不是 return 字符串,此方法 return 是 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 有一些通用的方法将我的数据从字符串缓冲区传输到另一个流中。
我是不是漏掉了什么?
感谢@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"));
}