TextDecoder: примеры (JAVASCRIPT)

Использование TextDecoder для преобразования бинарных данных в текст
Раздел: Текст, Кодировка
TextDecoder(label?: string, options?: TextDecoderOptions): TextDecoder

TextDecoder: декодирование бинарных данных в текст

Конструктор TextDecoder представляет собой встроенный объект JavaScript для преобразования (декодирования) последовательностей байтов, таких как Uint8Array, ArrayBuffer или DataView, в текстовые строки с учетом заданной кодировки.

Функция находит применение при работе с бинарными данными, полученными из сетевых запросов (например, fetch или XMLHttpRequest), файловых систем (File API) или других источников байтовых потоков.

Аргументы конструктора

Конструктор принимает два необязательных аргумента:

  • label (строка, необязательный): строка, определяющая кодировку декодера. По умолчанию используется 'utf-8'. Другие распространенные значения: 'utf-16le', 'windows-1251', 'iso-8859-1' и другие. Поддержка зависит от реализации браузера или среды выполнения.
  • options (объект, необязательный): объект с настройками. Единственное поддерживаемое свойство:
    • fatal (логическое значение): если true, то при встрече некодируемой последовательности декодирование завершится ошибкой. По умолчанию false, что приводит к замене невалидных символов символом замены Unicode (U+FFFD �).

Методы и свойства

Экземпляр TextDecoder обладает следующими основными свойствами и методами:

  • decode(input, options): основной метод для декодирования. Принимает ArrayBuffer, TypedArray или DataView. Возвращает строку.
  • encoding (только для чтения): кодировка декодера.
  • fatal (только для чтения): флаг, указывающий, является ли режим обработки ошибок фатальным.
  • ignoreBOM (только для чтения): флаг, указывающий, игнорируется ли метка порядка байтов (BOM).

Примеры базового использования

Декодирование из Uint8Array в UTF-8:

const encoder = new TextEncoder();
const data = encoder.encode('Привет, мир!'); // Uint8Array
const decoder = new TextDecoder('utf-8');
const result = decoder.decode(data);
console.log(result);
Привет, мир!

Декодирование из ArrayBuffer:

const buffer = new ArrayBuffer(5);
const view = new Uint8Array(buffer);
view[0] = 72; view[1] = 101; view[2] = 108; view[3] = 108; view[4] = 111;
const decoder = new TextDecoder();
console.log(decoder.decode(buffer));
Hello

Использование флага fatal в режиме замены ошибок (по умолчанию):

// Некорректная UTF-8 последовательность (один байт 0xFF)
const invalidData = new Uint8Array([0xFF]);
const decoder1 = new TextDecoder('utf-8', {fatal: false});
console.log(decoder1.decode(invalidData));

Использование флага fatal в строгом режиме:

const decoder2 = new TextDecoder('utf-8', {fatal: true});
try {
  decoder2.decode(invalidData);
} catch(e) {
  console.log('Ошибка:', e.name); // TypeError
}
Ошибка: TypeError

Похожие функции в JavaScript

  • String.fromCharCode() и String.fromCodePoint(): предназначены для создания строк из кодов символов (юникодных кодов). Работают на уровне кодовых точек, а не байтовых последовательностей. Не учитывают кодировку, поэтому подходят только для простых случаев с однобайтовыми кодировками (например, ASCII). TextDecoder является более мощным и универсальным решением для работы с бинарными данными.
  • Buffer.toString() (Node.js): в среде Node.js объект Buffer предоставляет метод toString() для декодирования бинарных данных в строку с указанием кодировки. По сути, является аналогом TextDecoder для Node.js, но с другим API.

Аналоги в других языках программирования

Python: для декодирования байтов используется метод decode() у объектов типа bytes или bytearray.

data = b'Hello World'
text = data.decode('utf-8')
print(text)  # Hello World
Hello World

PHP: функция mb_convert_encoding() или проще html_entity_decode() для определенных случаев, но чаще для преобразования бинарных данных из строк используют прямое присваивание или функцию pack()/unpack().

$binaryData = "\x48\x65\x6c\x6c\x6f";
$text = $binaryData; // В PHP строки могут содержать бинарные данные
// Явное указание кодировки часто не требуется, если это просто ASCII
echo $text;
Hello

C/C++: используются библиотечные функции, такие как MultiByteToWideChar (Windows) или iconv (Unix-подобные системы). Эти функции требуют больше ручного управления памятью и обработки ошибок по сравнению с TextDecoder.

Распространенные ошибки

1. Передача неверного типа аргумента в метод decode().

const decoder = new TextDecoder();
try {
  decoder.decode('это строка, а не ArrayBuffer');
} catch(e) {
  console.log(e.name); // TypeError
}
TypeError

2. Попытка декодировать данные в кодировке, не соответствующей исходной.

// Байты кириллицы в win-1251 декодируем как utf-8
const win1251Bytes = new Uint8Array([207, 240, 232, 226, 229, 242]); // 'Привет'
const decoderUtf8 = new TextDecoder('utf-8');
console.log(decoderUtf8.decode(win1251Bytes)); // Мусор
Ïðèâåò

3. Игнорирование необходимости правильного указания кодовой страницы для устаревших кодировок (например, windows-1251), что может приводить к отсутствию поддержки в некоторых средах.

Изменения в последних версиях

Стандарт TextDecoder стабилен и серьезных изменений в последних версиях ECMAScript не претерпел. Основные изменения касались улучшения поддержки различных кодировок и уточнения поведения в спецификации. В современных браузерах и Node.js (начиная с версии 11.0.0) TextDecoder является полностью поддерживаемой частью стандарта Encoding API.

Расширенные и специальные примеры

Декодирование потока данных по частям (stream decode):

Пример javascript
const decoder = new TextDecoder('utf-8');
let result = '';
// Имитация получения чанков данных
const chunks = [
  new Uint8Array([72, 101, 108]),  // Hel
  new Uint8Array([108, 111]),      // lo
  new Uint8Array([32, 87, 111, 114, 108, 100]) // World
];
for (const chunk of chunks) {
  result += decoder.decode(chunk, {stream: true});
}
// Декодирование любого оставшегося состояния декодера
result += decoder.decode();
console.log(result);
Hello World

Работа с кодировкой UTF-16LE:

Пример javascript
// Байты для 'AB' в UTF-16LE: A (0x41 0x00), B (0x42 0x00)
const utf16leData = new Uint8Array([0x41, 0x00, 0x42, 0x00]);
const decoder16 = new TextDecoder('utf-16le');
console.log(decoder16.decode(utf16leData));
AB

Декодирование с использованием DataView:

Пример javascript
const buffer = new ArrayBuffer(6);
const view = new DataView(buffer);
view.setUint8(0, 0x48); // H
view.setUint8(1, 0x65); // e
view.setUint8(2, 0x6C); // l
view.setUint8(3, 0x6C); // l
view.setUint8(4, 0x6F); // o
const decoder = new TextDecoder();
console.log(decoder.decode(view));
Hello

Чтение текстового файла в браузере с использованием FileReader и TextDecoder:

Пример javascript
// HTML: 
// Пример в контексте обработчика события
fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();
  reader.onload = (event) => {
    const arrayBuffer = event.target.result;
    const decoder = new TextDecoder('windows-1251'); // Пример для кириллицы
    const text = decoder.decode(arrayBuffer);
    console.log(text.slice(0, 100)); // Вывод первых 100 символов
  };
  reader.readAsArrayBuffer(file);
});

JS TextDecoder function comments

En
TextDecoder Decodes a stream of bytes into a string according to a specified character encoding.