如何在dart2js之后将二进制数据转换为utf8字符串

问题描述:

我将数据存储在localStorage中。因为我存储了很多数据,所以我需要压缩它。我用GZip做。一切正常,但我发现我从List转换成Gzip到Utf8的结果非常慢。在500k的数据上,在高速计算机上可能需要长达5分钟的时间。如何在dart2js之后将二进制数据转换为utf8字符串

问题主要出现在加载函数中。

负载:

import 'dart:convert'; 
import 'package:archive/archive.dart'; 
import 'package:crypto/crypto.dart'; 

var base64 = CryptoUtils.base64StringToBytes(window.localStorage[storageName]); 
var decompress = new GZipDecoder().decodeBytes(base64); 
storage = JSON.decode(new Utf8Decoder().convert(decompress)); 

节省:

var g = JSON.encode(storage); 
List<int> bz2 = new GZipEncoder().encode(new Utf8Encoder().convert(g)); 
window.localStorage[storageName] = CryptoUtils.bytesToBase64(bz2); 

难道我做错了什么?在Dart中有没有其他方式将列表转换为字符串?另外,我既保存又加载,所以不需要utf8。

我试过Ascii,但是它为不支持的字符引发错误。我有一种工作拉丁文1,其中有一个更高的性能,但我仍然得到一些不支持的字符。

+1

你正在浏览器上使用哪个GZipDecoder? – 2015-02-06 09:28:43

+0

我使用导入包中的GZipDecoder:archive/archive.dart';这很快,问题在于Utf8Decoder。 – darkzangel 2015-02-06 16:21:14

+1

我提交http://dartbug.com/22330。不过,我不确定我们什么时候有时间研究它。 (如果没有任何事情发生,请随时提醒我们该错误)。 – 2015-02-09 14:57:15

如果UTF-8是真正的瓶颈,你不需要它,你可以使用Dart的UTF-16本地字符串编码。

var compressed = new GZipEncoder().encode(str.codeUnits); 
var decompressed = new GZipDecoder().decodeBytes(compressed); 
var finalStr = new String.fromCharCodes(decompressed); 
+0

谢谢你,像一个魅力工作! :) – darkzangel 2015-02-06 16:58:15

这仅仅是一个黑客,是不是最好的,但它的工作原理和它给了我不错的表现,现在:

String convertListIntToUtf8(List<int> codeUnits) { 
    var endIndex = codeUnits.length; 
    StringBuffer buffer = new StringBuffer(); 
    int i = 0; 
    while (i < endIndex) { 
    var c = codeUnits[i]; 
    if (c < 0x80) { 
     buffer.write(new String.fromCharCode(c)); 
     i += 1; 
    } else if (c < 0xE0) { 
     buffer.write(new String.fromCharCode((c << 6) + codeUnits[i+1] - 0x3080)); 
     i += 2; 
    } else if (c < 0xF0) { 
     buffer.write(new String.fromCharCode((c << 12) + (codeUnits[i+1] << 6) + codeUnits[i+2] - 0xE2080)); 
     i += 3; 
    } else { 
     buffer.write(new String.fromCharCode((c << 18) + (codeUnits[i+1] << 12) + (codeUnits[i+2] << 6) + codeUnits[i+3] - 0x3C82080)); 
     i += 4; 
    } 
    if (i >= endIndex) break; 
    } 
    return buffer.toString(); 
}