23日 十月 2019

文本解码器(TextDecoder) 和 文本编码器(TextEncoder)

如果二进制数据实际上是一个字符串怎么办?例如,我们收到了一个包含文本数据的文件。

内置的 TextDecoder 对象在给定缓冲区(buffer)和编码格式(encoding)的情况下,能够将值读取到实际的 JavaScript 字符串中。

首先我们需要创建:

let decoder = new TextDecoder([label], [options]);
  • label – 编码格式,默认为 utf-8,但同时也支持 big5windows-1251 等许多其他编码格式。
  • options – 可选对象:
    • fatal – 布尔值,如果为 true 则抛出无效(不可解码)字符异常,否则(默认)替换为字符 \uFFFD
    • ignoreBOM – 布尔值,如果为 true 则忽略字节顺序标记(BOM)(可选的字节顺序统一码(Unicode)标记),极少情况会需要。

…… 然后开始解码:

let str = decoder.decode([input], [options]);
  • input – 要被解码的 BufferSource
  • options – 可选对象:
    • stream – true 为解码流(streams),这时候 decoder 会以传入的数据块(chunks)为参数被重复调用。这种情况下,多字节的字符可能偶尔会在块与块之间被分割。这个选项告诉 TextDecoder 去记住 “未完成” 的字符并且在下一个数据块来的时候进行解码。

例如:

let uint8Array = new Uint8Array([72, 101, 108, 108, 111]);

alert( new TextDecoder().decode(uint8Array) ); // Hello
let uint8Array = new Uint8Array([228, 189, 160, 229, 165, 189]);

alert( new TextDecoder().decode(uint8Array) ); // 你好

我们可以通过为其创建子数组视图来解码部分缓冲区:

let uint8Array = new Uint8Array([0, 72, 101, 108, 108, 111, 0]);

// 该字符串位于中间
// 在不复制任何内容的前提下,创建一个新的视图
let binaryString = uint8Array.subarray(1, -1);

alert( new TextDecoder().decode(binaryString) ); // Hello

文本编码器

TextEncoder 做了相反的事情 – 将字符串转换为字节。

语法为:

let encoder = new TextEncoder();

支持的编码格式只有 utf-8

它有两种方法:

  • encode(str) – 返回一个字符串被转换得到的 Uint8Array
  • encodeInto(str, destination) – 将 str 编码到 destination中,该目标必须为 Uint8Array
let encoder = new TextEncoder();

let uint8Array = encoder.encode("Hello");
alert(uint8Array); // 72,101,108,108,111
教程路线图

评论

在评论之前先阅读本内容…
  • 如果你发现教程有错误,或者有其他需要修改和提升的地方 — 请 提交一个 GitHub issue 或 pull request,而不是在这评论。
  • 如果你对教程的内容有不理解的地方 — 请详细说明。
  • 使用 <code> 标签插入只有几个词的代码,插入多行代码可以使用 <pre> 标签,对于超过 10 行的代码,建议你使用沙箱(plnkrJSBincodepen…)