在 JavaScript 中将 ArrayBuffer 转换为字符串,可以使用 TextDecoder API。TextDecoder 可从字节序列中解码文本内容,支持多种编码格式。
以下是将 ArrayBuffer 转换为字符串的示例代码:
// 假设 ArrayBuffer 对象为 buffer
const decoder = new TextDecoder('utf-8');
const text = decoder.decode(buffer);在上面的代码中,我们创建了一个 TextDecoder 对象,使用
utf-8
编码对ArrayBuffer
进行解码,并将解码后的文本存储在变量 text 中。如果 ArrayBuffer 中存储的是
GB2312
编码的文本,可以将utf-8
编码修改为gb2312
。您还可以封装为函数,以便于使用:
function arrayBufferToString(buffer, encoding = 'utf-8') {
const decoder = new TextDecoder(encoding);
return decoder.decode(buffer);
}这个函数接收两个参数,第一个参数表示要转换的 ArrayBuffer 对象,第二个参数为编码格式(默认为'utf-8')。 返回转换后的字符串。调用该函数的方式如下所示:
const buffer = new ArrayBuffer(2);
const intArray = new Uint8Array(buffer);
intArray[0] = 72;
intArray[1] = 105;
const str = arrayBufferToString(buffer);
console.log(str); // Output: Hi01 实际问题 - 网页乱码
nodejs
使用axios
写爬虫时Response
乱码,经查查发现网页编码是gb2312
的。则我们可以通过返回arraybuffer
的方式,再重新编码即可。const { data } = await axios.get('http://xxx.y.z', { responseType: 'arraybuffer'});
const normalStrig = arrayBufferToString(Buffer.from(data), 'gb2312'); // 返回正确的字符串02 技术细节 - ArrayBuffer、Int32Array等
ArrayBuffer
是一种用于在 JavaScript 中存储二进制数据的对象,可以看做是一个固定大小的字节缓冲区。可以使用 ArrayBuffer 来存储任意类型的二进制数据,包括数字、图像、音频等等。
Int32Array
是一种类型化数组(TypedArray),它只能存储32 位
整数类型的数据。具体来说,Int32Array 可以存储范围在-2147483648 ~ 2147483647
之间的整数数据,也就是 JavaScript 中的 32 位有符号整数类型。Int32Array 中每一项都占用 4 个字节,使用 Int32Array 对象可以快速地读取和写入 ArrayBuffer 中的 32 位整数数据,适合处理大量数据的场景。
除了 Int32Array,还有一些其他的类型化数组也可以用于存储不同类型的数据,包括:
Int8Array:1 个字节的有符号整数类型,范围在 -128 ~ 127 之间; Uint8Array:1 个字节的无符号整数类型,范围在 0 ~ 255 之间; Uint16Array:2 个字节的无符号整数类型,范围在 0 ~ 65535 之间; Int16Array:2 个字节的有符号整数类型,范围在 -32768 ~ 32767 之间; Uint32Array:4 个字节的无符号整数类型,范围在 0 ~ 4294967295 之间; Float32Array:4 个字节的单精度浮点数类型; Float64Array:8 个字节的双精度浮点数类型。 以上这些类型化数组都只能存储指定类型的数据,并且每一项占用的字节数都是固定的。使用类型化数组可以轻松地读取和写入 ArrayBuffer 中指定类型的数据,提高数据读写的效率。
03 技术举例
Uint8Array 和 Uint32Array 都是类型化数组(TypedArray),但它们的应用场景和使用方式有所不同。
Uint8Array 适用于存储任意的 8 位无符号整数类型的数据,每一项占用一个字节。可以通过数组下标的方式直接访问和修改其中的数据。
以下是 Uint8Array 的一个例子,使用它来将一个字符串编码成 UTF-8 的字节数组:
function encodeUTF8(str) {
const codePoints = Array.from(str, c => c.codePointAt(0));
const buffer = new ArrayBuffer(codePoints.length * 4);
const uint8Array = new Uint8Array(buffer);
let offset = 0;
for (let i = 0; i < codePoints.length; i++) {
const codePoint = codePoints[i];
if (codePoint < 0x80) {
uint8Array[offset++] = codePoint;
} else if (codePoint < 0x800) {
uint8Array[offset++] = 0xC0 | (codePoint >> 6);
uint8Array[offset++] = 0x80 | (codePoint & 0x3F);
} else if (codePoint < 0x10000) {
uint8Array[offset++] = 0xE0 | (codePoint >> 12);
uint8Array[offset++] = 0x80 | ((codePoint >> 6) & 0x3F);
uint8Array[offset++] = 0x80 | (codePoint & 0x3F);
} else {
uint8Array[offset++] = 0xF0 | (codePoint >> 18);
uint8Array[offset++] = 0x80 | ((codePoint >> 12) & 0x3F);
uint8Array[offset++] = 0x80 | ((codePoint >> 6) & 0x3F);
uint8Array[offset++] = 0x80 | (codePoint & 0x3F);
}
}
return uint8Array.subarray(0, offset);
}
const str = "Hello, 世界!";
const byteArr = encodeUTF8(str);
console.log(byteArr);在上面的代码中,我们通过
new Uint8Array(buffer)
创建了一个长度为codePoints.length * 4
的 Uint8Array 对象uint8Array
,即总共分配了足够存储 UTF-8 字节数组的缓存空间。然后通过对字符的 Unicode 编码进行判断,将每个字符转换为对应的 UTF-8 字节序列,并存储到uint8Array
中。最后通过uint8Array.subarray(0, offset)
返回仅包含有效数据的 Uint8Array 视图对象。Uint32Array 适用于存储任意的 32 位无符号整数类型的数据,每一项占用 4 个字节。可以通过数组下标的方式直接访问和修改其中的数据。
好的,以下是一个使用 Uint32Array 在 JavaScript 中实现求素数的例子:
技巧 | 03 JavaScript 中将 ArrayBuffer 转换为字符串
·
阅读需 8 分钟