使用 java 解析 JSON 时,如何获取受最大数量限制的 Text()?



我正在尝试解析Apache Tika Server的rmetaWeb servivce端点的输出:https://cwiki.apache.org/confluence/display/TIKA/TikaServer#TikaServer-RecursiveMetadataandContent

它的有效负载如下所示:

[
{"Application-Name":"Microsoft Office Word",
"Application-Version":"15.0000",
"X-Parsed-By":["org.apache.tika.parser.DefaultParser","org.apache.tika.parser.microsoft.ooxml.OOXMLParser"],
"X-TIKA:content":"this content string can be many MB large"
...
},
{"Content-Encoding":"ISO-8859-1",
"Content-Length":"8",
"Content-Type":"text/plain; charset=ISO-8859-1"
"X-TIKA:content":"again, this content string can be many MB large",
...
}
...
]

如前所述,X-TIKA:content弦可能非常大。如果我将整个字符串加载到内存中,足以 OOM 我的 JVM。

因此,如果我像这样使用JsonParser.getText()

private void parseRmetaResponse(CloseableHttpResponse response) {
ObjectMapper objectMapper = new ObjectMapper();
JsonFactory jsonFactory = objectMapper.getFactory();
JsonParser jsonParser = jsonFactory.createParser(response.getEntity().getContent());
JsonToken arrayStartToken = jsonParser.nextToken();
if (arrayStartToken != JsonToken.START_ARRAY) {
throw new IllegalStateException("The first element of the Json structure was expected to be a start array token, but it was: " + arrayStartToken);
}

JsonToken nextToken = jsonParser.nextToken();
while (nextToken != JsonToken.END_ARRAY) {
parseNextField(jsonParser);
}
}
private String getTextContents(JsonParser jsonParser, OutputStream os, Metadata metadata) throws IOException {
String nextAttr = jsonParser.nextFieldName();
if ("X-TIKA:content".equals(nextAttr)) {
return jsonParser.getText();
}
// ...
}

它很容易发生 OOM 崩溃,因为我无法在不占用所有 JVM 堆的情况下将所有字符串加载到内存中。

相反,我有一个最大数量的字符参数maxChars我想在达到该数字后停止从X-TIKA:content读取字符。

我怎么能说"给我发短信,但最多只能读取maxChars个字符,并丢弃任何其他字符"?

我可以使用GSON,Fasterxml Jackson或任何其他可以帮助我完成我需要做的事情的库。

可以调用int getText(Writer writer),而不是调用String getText()

给它一个类似于StringWriter的自定义Writer,但丢弃任何超过给定阈值的字符。

你会像这样使用它:

if ("X-TIKA:content".equals(nextAttr)) {
try (LimitedStringWriter writer = new LimitedStringWriter(maxParseChars)) {
jsonParser.getText(writer);
return writer.toString();
}
}

编写LimitedStringWriter类是你的工作。


由提问者(Nicholas DiPiazza(添加(:
下面是一个可以用作示例的实现示例:https://github.com/ow2-proactive/scheduling/blob/master/common/common-api/src/main/java/org/ow2/proactive/utils/BoundedStringWriter.java

相关内容

  • 没有找到相关文章

最新更新