创建JSON包装结构时,如何避免将InputStream转String写入JsonGenerator?
避免将InputStream转成String直接写入JSON包装的方法
当然可以避免把InputStream转成String,利用Jackson的JsonGenerator提供的重载方法,直接流式读取输入流内容写入即可,这样能大幅降低内存占用,尤其适合大容量JSON数据场景。
修改后的实现代码
//Method to frame the outer wrapper elements for the JSON. private InputStream generateJsonWrapper(final InputStream usersList) throws IOException { final JsonFactory jsonFactory = new JsonFactory(); final StringWriter jsonObjectWriter = new StringWriter(); final JsonGenerator jsonGenerator = jsonFactory.createGenerator(jsonObjectWriter); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("type", "customerDocument"); jsonGenerator.writeStringField("creationDate", Instant.now().toString()); jsonGenerator.writeObjectFieldStart("customerBody"); jsonGenerator.writeFieldName("customerList"); // 直接用Reader流式读取InputStream,避免转成完整String try (InputStreamReader reader = new InputStreamReader(usersList, StandardCharsets.UTF_8)) { jsonGenerator.writeRawValue(reader); } jsonGenerator.writeEndObject(); jsonGenerator.writeEndObject(); jsonGenerator.flush(); jsonGenerator.close(); return new ByteArrayInputStream(jsonObjectWriter.toString().getBytes(StandardCharsets.UTF_8)); }
关键改动说明
- 移除冗余代码:删掉了原代码中重复的
jsonfactory.createGenerator(jsonObjectWriter);语句,这行完全多余。 - 流式写入原始JSON内容:用
InputStreamReader包装输入流,直接传给writeRawValue(Reader)方法。这个方法会逐字符读取输入流内容并写入生成器,不会一次性把整个JSON数组加载到内存中,完美适配大容量数据场景。 - 资源自动管理:用try-with-resources包裹
InputStreamReader,确保输入流资源能被正确关闭,避免资源泄漏。
额外优化建议
如果最终输出也想避免生成完整的String(比如超大数据场景),可以直接把JsonGenerator绑定到OutputStream,而不是StringWriter,进一步减少内存占用:
private InputStream generateJsonWrapper(final InputStream usersList) throws IOException { final JsonFactory jsonFactory = new JsonFactory(); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final JsonGenerator jsonGenerator = jsonFactory.createGenerator(baos, StandardCharsets.UTF_8); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("type", "customerDocument"); jsonGenerator.writeStringField("creationDate", Instant.now().toString()); jsonGenerator.writeObjectFieldStart("customerBody"); jsonGenerator.writeFieldName("customerList"); try (InputStreamReader reader = new InputStreamReader(usersList, StandardCharsets.UTF_8)) { jsonGenerator.writeRawValue(reader); } jsonGenerator.writeEndObject(); jsonGenerator.writeEndObject(); jsonGenerator.flush(); jsonGenerator.close(); return new ByteArrayInputStream(baos.toByteArray()); }
这个优化把中间的StringWriter换成了ByteArrayOutputStream,减少了一次字符串和字节数组的转换开销,内存效率更高。
内容的提问来源于stack exchange,提问作者SUPERMAN
相关产品推荐
相关产品推荐

