编辑输入流并将其作为流写入,而无需在任何给定时间将其所有内容存储到内存中



我有一个方法,它接收JSON格式的InputStream数据。使用Jackson的ObjectMapper,我能够将InputStream转换为可以编辑的JsonNode,如下所示:

JsonNode revisions = mapper.readTree(data);

从那里,我可以迭代每个元素并进行更改。不过,在这样做的过程中,我将所有元素存储在一个列表中,然后将该列表转换为Stream。我更喜欢从InputStream一次对每个元素进行一个操作,这样我就不必将其全部存储在内存中。

这是我的:

public Stream<Revision> jsonToRevisionObjects(InputStream allData) throws IOException {
    // convert the InputStream to a JsonNode
    JsonNode revisions = mapper.readTree(allData);
    List<Revision> newRevisions = new ArrayList<>();
    for (JsonNode revision : revisions.get("results")) {
        // create Revision objects and add them to newRevisions
    }
    return newRevisions.stream();
}

这基本上违背了使用Stream的意义,因为我将所有新的Revision对象存储到内存中。相反,我希望一次读取一个元素,并在加载下一个元素之前将其发送到流中。有办法做到这一点吗?根据周围的代码,输入参数将始终是InputStream(存在问题),返回类型将始终是Stream。

如果我能够将InputStream转换为Stream并执行以下操作,这可能是可能的:

return allDataStream.map(rev -> {
    // create Revision object
       });

但如果有可能的话,我不知道如何达到这一点。

要使用流式读取,必须直接使用JsonParser,或将其传递给ObjectMapper/ObjectReader。如果是这样的话,如果你想的话,你可以把子树读成JsonNode

InputStream构建JsonParser很简单:

JsonParser p=mapper.getFactory().createParser(inputStream);

但是在此之后的操作变化;您可以直接从JsonParser读取令牌流,也可以要求ObjectMapperObjectReader从流中读取下一个"值"。然后JSON数据的结构很重要;如果您想避免读取所有内容,您可能需要提前解析器的流(nextToken())。

相关内容

  • 没有找到相关文章

最新更新