在GWT客户端中导致“超出最大调用堆栈大小”的新字符串(字节)

时间:2015-09-29 12:37:39

标签: java gwt

以下适用于短字符串

result = new String(bytes);

我有一个大约140000字节的byte [],当我尝试使用上面的代码从中创建String时,浏览器会抛出异常Maximum call stack size exceeded。我正在使用Using GWT 2.6.0。

我相信在创建大型数组时可能抛出此异常,但我找不到另一种方法来从GWT中的byte []创建字符串。我可以使用任何建议或解决方法来实现这项工作吗?

JavaScript异常和调用堆栈如下所示。

Uncaught RangeError: Maximum call stack size exceeded
valueOf_86  @   String.java:630
utf8ToString    @   String.java:210
_String_0   @   String.java:322
_String_1   @   String.java:237
handleHttpResponse_7    @   BaseRequest.java:38
onResponseReceived  @   GwtNet.java:56
$fireOnResponseReceived @   Request.java:315
onReadyStateChange_1    @   RequestBuilder.java:42
(anonymous function)    @   XMLHttpRequest.java:402
apply_24    @   Impl.java:58
entry0  @   Impl.java:385
(anonymous function)    @   Impl.java:91

1 个答案:

答案 0 :(得分:1)

我无法解决这个问题,所以我最终写了一个方法来将UTF-8字节数组切成块并按块解码它。如果有人知道更好的方式,那么请发一个新答案。

/**
 * Decoding very long strings in GWT causes exceptions, so anything that could be decoding a large string in
 * GWT must use this method instead
 * @param bytes The array of UTF-8 bytes
 * @return String representation of the array
 * @throws UnsupportedEncodingException
 */
public static String getUTF8String(byte[] bytes) throws UnsupportedEncodingException {
    StringBuilder stringBuilder = new StringBuilder();
    int charLength;
    int lastDecodeOffset = 0;
    int charCount = 0;

    int offset = 0;
    while (offset < bytes.length) {
        if ((bytes[offset] & 0b10000000) == 0b00000000) charLength = 1;
        else if ((bytes[offset] & 0b11100000) == 0b11000000) charLength = 2;
        else if ((bytes[offset] & 0b11110000) == 0b11100000) charLength = 3;
        else if ((bytes[offset] & 0b11111000) == 0b11110000) charLength = 4;
        else if ((bytes[offset] & 0b11111100) == 0b11111000) charLength = 5;
        else if ((bytes[offset] & 0b11111110) == 0b11111100) charLength = 6;
        else throw new UnsupportedEncodingException("Invalid UTF-8 data");

        if (offset + charLength > bytes.length) {
            throw new UnsupportedEncodingException("Invalid UTF-8 data");
        }

        offset += charLength;
        charCount++;

        if (charCount > 2048 || offset >= bytes.length) {
            stringBuilder.append(new String(bytes, lastDecodeOffset, offset - lastDecodeOffset, "UTF-8"));
            lastDecodeOffset = offset;
            charCount = 0;
        }
    }

    return stringBuilder.toString();
}