gpt4 book ai didi

java - Base64 值导致 SAX 解析器中的 StringBuilder.append 内存不足错误

转载 作者:行者123 更新时间:2023-12-02 00:59:03 30 4
gpt4 key购买 nike

我正在使用 SAX 解析器来解析 XML 文件,该文件是来自客户端服务器的响应。标签内有文件的 Base64 解码值(jpg、png、pdf 等)。其中一些我可以轻松写入文件,但对于其中一些(我猜是大的),我在 StringBuilder.append 期间在 DefaultHandler 的覆盖方法上遇到问题:

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (valueActive) { // set to true only when <value> tag is active
stringBuilder.append(ch, start, length); // OUT OF MEMORY error
}
}

在接下来的步骤中,我将使用 Base64Encoder 来写入文件:

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {

if (qName.equalsIgnoreCase("value")) {

valueActive = false;

try (OutputStream stream = new FileOutputStream(my file here)) {

base64 = Base64.getDecoder().decode(stringBuilder.toString());

stream.write(base64);
} catch .... / omitted part of code
}

有人可以建议如何解决内存不足问题吗?堆栈跟踪:

Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:596)
at java.lang.StringBuilder.append(StringBuilder.java:190)
at com....AttachmentHandler.characters(AttachmentHandler.java:47)

编辑:

Base64 来自 XML:

<value> String encoded with base64 </value>

对于 SAX 解析器,我使用 RestTemplate:

@Override
@Retryable
public Application performMultimediaRequest(String url) {

SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();

try {
SAXParser saxParser = saxParserFactory.newSAXParser();

restTemplate.execute(url,
HttpMethod.GET,
null,
responseExtractor -> {
try {
saxParser.parse(responseExtractor.getBody(), attachmentHandler);
} catch (SAXException e) {
log.error("Cannot parse API response with SAX parser");
}
return null;
}
);
} catch (SAXException | ParserConfigurationException e) {
log.error("Cannot parse response with SAX parser");
}

return attachmentHandler.getApplication();
}

最佳答案

增加 JVM 堆内存以容纳 StringBuilder内存要求或使用 Base64.getDecorder().wrap(InputStream) 方法:

Returns an input stream for decoding Base64 encoded byte stream.

The read methods of the returned InputStream will throw IOException when reading bytes that cannot be decoded.

Closing the returned input stream will close the underlying input stream.

您的示例代码的问题是它不完整,我们不知道您从哪里获得 char值(value)。如果您收到 char值来自 InputStream您已完成 wrap() 的工作.

您可以通过从 Base64.getDecorder().decode(String) 切换来减少总体内存需求至Base64.getDecorder().decode(byte[])但如果您想节省堆内存,您应该重写代码以使用 InputStream并且不要创建临时 Stringbyte[] .

关于java - Base64 值导致 SAX 解析器中的 StringBuilder.append 内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60936281/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com