August 20, 2019

TextDecoder и TextEncoder

Что если бинарные данные фактически являются строкой? Например, мы получили файл с текстовыми данными.

Встроенный объект TextDecoder позволяет декодировать данные из бинарного буфера в обычную строку.

Для этого прежде всего нам нужно создать сам декодер:

let decoder = new TextDecoder([label], [options]);
  • label – тип кодировки, utf-8 используется по умолчанию, но также поддерживаются big5, windows-1251 и многие другие.
  • options – объект с дополнительными настройками:
    • fatal – boolean, если значение true, тогда генерируется ошибка для невалидных (не декодируемых) символов, в ином случае (по умолчанию) они заменяются символом \uFFFD.
    • ignoreBOM – boolean, если значение true, тогда игнорируется BOM (дополнительный признак, определяющий порядок следования байтов), что необходимо крайне редко.

…и после использовать его метод decode:

let str = decoder.decode([input], [options]);
  • input – бинарный буфер (BufferSource) для декодирования.
  • options – объект с дополнительными настройками:
    • stream – true для декодирования потока данных, при этом decoder вызывается вновь и вновь для каждого следующего фрагмента данных. В этом случае многобайтовый символ может иногда быть разделён и попасть в разные фрагменты данных. Это опция указывает 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

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.
  • Для одной строки кода используйте тег <code>, для нескольких строк кода — тег <pre>, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)
  • Если что-то непонятно в статье — пишите, что именно и с какого места.