Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Base64值导致SAX解析器中出现StringBuilder.append内存不足错误_Java_Xml Parsing_Base64_Stringbuilder_Saxparser - Fatal编程技术网

Java Base64值导致SAX解析器中出现StringBuilder.append内存不足错误

Java Base64值导致SAX解析器中出现StringBuilder.append内存不足错误,java,xml-parsing,base64,stringbuilder,saxparser,Java,Xml Parsing,Base64,Stringbuilder,Saxparser,我使用SAX解析器来解析XML文件,它是来自客户端服务器的响应。标签包含在文件(jpg、png、pdf等)的Base64解码值中。其中一些我可以轻松写入文件,但其中一些(我猜是大的)在使用DefaultHandler的Overwrited方法执行StringBuilder.append时出现问题: @Override public void characters(char[] ch, int start, int length) throws SAXException { if (val

我使用SAX解析器来解析XML文件,它是来自客户端服务器的响应。标签包含在文件(jpg、png、pdf等)的Base64解码值中。其中一些我可以轻松写入文件,但其中一些(我猜是大的)在使用DefaultHandler的Overwrited方法执行StringBuilder.append时出现问题:

@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
    }
}
有人能建议如何解决内存不足问题吗?堆栈跟踪:

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>

增加JVM堆内存以满足
StringBuilder
内存需求,或者使用以下方法:

返回用于解码Base64编码字节流的输入流

当读取无法解码的字节时,返回InputStream的读取方法将抛出IOException

关闭返回的输入流将关闭底层输入流

示例代码的问题是它不完整,我们不知道从哪里获得
char
值。如果要从
InputStream
获取
char
值,则需要对
wrap()
进行裁剪


您可以希望通过从
Base64.getDecorder().decode(String)
切换到
Base64.getDecorder().decode(byte[])
来降低总体内存需求,但是如果您想保存堆内存,您应该重写代码以使用
InputStream
,并且不要创建临时
String
byte[]

增加JVM堆内存以满足
StringBuilder
内存要求,或者使用以下方法:

返回用于解码Base64编码字节流的输入流

当读取无法解码的字节时,返回InputStream的读取方法将抛出IOException

关闭返回的输入流将关闭底层输入流

示例代码的问题是它不完整,我们不知道从哪里获得
char
值。如果要从
InputStream
获取
char
值,则需要对
wrap()
进行裁剪


您可以希望通过从
Base64.getDecorder().decode(String)
切换到
Base64.getDecorder().decode(byte[])
来降低总体内存需求,但是如果您想保存堆内存,您应该重写代码以使用
InputStream
,并且不要创建临时
String
byte[]

我刚刚编辑了这个问题,并将Base64从何处添加到SAX解析器中。当值标记处于活动状态时,我使用SAX解析器的characters方法,正如您已经提到的,最好使用InputStream,但是,我在实现这一点时遇到了一些问题。具体来说,我不知道如何在characters方法中将来自SAX的char数组添加到一个InputStream中。此外,当我稍后使用Base64.getDecorder().wrap(InputStream)时,我将获得InputStream,而不是可以将其与文件一起添加到OutputStream的字节[]。感谢您提供的一些建议。我刚刚编辑了这个问题,并添加了Base64到SAX解析器的来源。当值标记处于活动状态时,我使用SAX解析器的characters方法,正如您已经提到的,最好使用InputStream,但是,我在实现这一点时遇到了一些问题。具体来说,我不知道如何在characters方法中将来自SAX的char数组添加到一个InputStream中。此外,当我稍后使用Base64.getDecorder().wrap(InputStream)时,我将获得InputStream,而不是可以将其与文件一起添加到OutputStream的字节[]。谢谢你给我的建议。
<value> String encoded with base64 </value>
@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();
}