如何在dart2js之后将二进制数据转换为utf8字符串
How to convert binary data to utf8 string after dart2js
我正在将我的数据存储在 localStorage 中。因为我存了很多数据,所以需要压缩一下。我用 GZip 来做。一切正常,但我发现我从 GZip 的结果列表到 Utf8 的转换非常慢。对于 500k 的数据,在快速计算机上最多可能需要 5 分钟。
问题主要出现在加载函数中。
加载:
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,但它会抛出不支持字符的错误。我有点工作 latin1,为此性能更高,但我仍然得到一些不受支持的字符。
这只是一个 hack,不是最好的,但它确实有效,而且它现在给了我很好的性能:
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();
}
如果 UTF-8 确实是瓶颈,而您不需要它,您可以只使用 Dart 的原生字符串编码,即 UTF-16。
var compressed = new GZipEncoder().encode(str.codeUnits);
var decompressed = new GZipDecoder().decodeBytes(compressed);
var finalStr = new String.fromCharCodes(decompressed);
我正在将我的数据存储在 localStorage 中。因为我存了很多数据,所以需要压缩一下。我用 GZip 来做。一切正常,但我发现我从 GZip 的结果列表到 Utf8 的转换非常慢。对于 500k 的数据,在快速计算机上最多可能需要 5 分钟。
问题主要出现在加载函数中。
加载:
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,但它会抛出不支持字符的错误。我有点工作 latin1,为此性能更高,但我仍然得到一些不受支持的字符。
这只是一个 hack,不是最好的,但它确实有效,而且它现在给了我很好的性能:
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();
}
如果 UTF-8 确实是瓶颈,而您不需要它,您可以只使用 Dart 的原生字符串编码,即 UTF-16。
var compressed = new GZipEncoder().encode(str.codeUnits);
var decompressed = new GZipDecoder().decodeBytes(compressed);
var finalStr = new String.fromCharCodes(decompressed);