将ArrayBuffer转为String
问题近期有个项目需要通过小程序配置设备,协议通过蓝牙传输裸的数据流,牵涉到js端将ArrayBuffer组装成String。方法由于 ArrayBuffer 实际上是一个字节数组,因此这种转换要求两端就如何将 String 中的字符表示为字节达成一致。 您之前可能已经看过这个“协议”:它是字符串的字符编码(通常的“协议条款”是,例如,Unicode UTF-16 和 iso8859-1)。 因此,
问题
近期有个项目需要通过小程序配置设备,协议通过蓝牙传输裸的数据流,牵涉到js端将ArrayBuffer组装成String。
方法
由于 ArrayBuffer 实际上是一个字节数组,因此这种转换要求两端就如何将 String 中的字符表示为字节达成一致。 您之前可能已经看过这个“协议”:它是字符串的字符编码(通常的“协议条款”是,例如,Unicode UTF-16 和 iso8859-1)。 因此,假设您和对方已就 UTF-16 编码达成一致,则转换代码可能类似于:
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function str2ab(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
注意:Uint16Array的用法。这是一个ArrayBuffer视图,它将数组缓冲区的字节对齐为16位元素。它本身不处理字符编码,字符编码是由String.fromCharCode和str.charCodeAt作为Unicode处理的。
ArrayBuffers 用于传输原始数据,一些新的 API 依赖于它们,包括 WebSockets、Web Intents、XMLHttpRequest2 和 WebWorkers。 然而,由于它们最近才被引入 JavaScript 世界,因此有时会被曲解或误用。
从语义上讲,ArrayBuffer 只是通过特定掩码查看的字节数组。 这个掩码是 ArrayBufferView 的一个实例,定义了字节如何对齐以匹配内容的预期结构。 例如,如果您知道 ArrayBuffer 中的字节表示一个 16 位无符号整数数组,您只需将 ArrayBuffer 包装在 Uint16Array
视图中,您就可以使用方括号语法操作其元素,就好像 Uint16Array
是一个整数数组一样:
// suppose buf contains the bytes [0x02, 0x01, 0x03, 0x07]
// notice the multibyte values respect the hardware endianess, which is little-endian in x86
var bufView = new Uint16Array(buf);
if (bufView[0]===258) { // 258 === 0x0102
console.log("ok");
}
bufView[0] = 255; // buf now contains the bytes [0xFF, 0x00, 0x03, 0x07]
bufView[0] = 0xff05; // buf now contains the bytes [0x05, 0xFF, 0x03, 0x07]
bufView[1] = 0x0210; // buf now contains the bytes [0x05, 0xFF, 0x10, 0x02]
使用TextEncoder或TextDecoder
if (!("TextEncoder" in window))
alert("Sorry, this browser does not support TextEncoder...");
var enc = new TextEncoder(); // always utf-8
console.log(enc.encode("This is a string converted to a Uint8Array"));
TextDecoder 接口代表特定方法的解码器,即特定的字符编码,如 utf-8、iso-8859-2、koi8、cp1261、gbk、…解码器将字节流作为输入并发出 码点流。
if (!("TextDecoder" in window))
alert("Sorry, this browser does not support TextDecoder...");
var enc = new TextDecoder("utf-8");
var arr = new Uint8Array([84,104,105,115,32,105,115,32,97,32,85,105,110,116,
56,65,114,114,97,121,32,99,111,110,118,101,114,116,
101,100,32,116,111,32,97,32,115,116,114,105,110,103]);
console.log(enc.decode(arr));
参考文章
更多推荐
所有评论(0)