Преобразование строк и ArrayBuffers в JavaScript
Быстрый ответ
Для того чтобы преобразовать строку в ArrayBuffer, используйте метод new TextEncoder().encode(string);
. Для обработки в обратном порядке, т.е декодирования ArrayBuffer в строку, подойдет метод new TextDecoder().decode(arrayBuffer);
.
// Перевод строки в ArrayBuffer
const arrayBuffer = new TextEncoder().encode("Привет, мир!");
// Преобразование ArrayBuffer в строку
const decodedString = new TextDecoder().decode(arrayBuffer);
Эти кодовые сниппеты иллюстрируют надежный и простой подход к преобразованию строк и ArrayBuffer.
Преобразование и обработка с использованием разных кодировок
Выбор кодировки
Для правильного декодирования можно указать необходимую кодировку при инициализации TextDecoder
.
// Задаем кодировку для декодирования
const decoder = new TextDecoder('utf-8');
const text = decoder.decode(arrayBuffer);
// Вот и готов наш текст в кодировке UTF-8
Однако следует заметить, что в данный момент TextEncoder
поддерживает лишь UTF-8 на большинстве современных браузеров. Учитывая широкое распространение UTF-8 в интернете, это достаточно для большинства ситуаций.
Альтернативы и совместимость
Для обеспечения совместимости в разных браузерах, убедитесь в поддержке TextEncoder
и TextDecoder
в браузере пользователя. Если они отсутствуют, используйте полифилы, такие как библиотека stringencoding
.
if (window.TextEncoder && window.TextDecoder) {
// Отлично, TextEncoder и TextDecoder поддерживаются.
} else {
// Нужно загрузить полифил или использовать другой подход, как будто мы возвращаемся к проблеме Y2K.
}
Эффективное хранение с UTF-16
Если нужно сохранить ArrayBuffer
в localStorage, который поддерживает только строки, данные можно преобразовать в строку с использованием кодировки UTF-16. Это поможет более эффективно использовать память, чем при использовании других методов.
// Сохраняем ArrayBuffer в localStorage с использованием кодировки UTF-16
const str = String.fromCharCode.apply(null, new Uint16Array(arrayBuffer));
localStorage.setItem('key', str);
// Теперь ArrayBuffer сохранен в localStorage!
Для извлечения и возвращения данных обратно в ArrayBuffer нужно сделать так:
const storedStr = localStorage.getItem('key');
const buffer = new Uint16Array(storedStr.split('').map(char => char.charCodeAt(0))).buffer;
// Данные успешно восстановлены!
Подход Скайуокера к преобразованию данных
Работа с большими объемами данных
Если вам приходится обрабатывать огромные объемы данных или бинарные файлы, то могут возникнуть проблемы с размером стека. В таком случае работайте с данными по частям.
// Преобразование большого ArrayBuffer в строку
function largeArrayBufferToString(arrayBuffer) {
const chunkSize = 65535; // Максимальный размер блока данных.
const uint16Array = new Uint16Array(arrayBuffer);
let string = '';
let i = 0;
while(i < uint16Array.length) {
const subArray = uint16Array.subarray(i, Math.min(i + chunkSize, uint16Array.length));
string += String.fromCharCode.apply(null, subArray);
i += chunkSize;
}
return string;
}
В процессе кодирования данные также следует разбить на части, применяя аналогичную стратегию.
Управление процессом декодирования
Для более полного контроля над процессом декодирования используйте DataView
, который дает возможность работать с данными на уровне байтов.
// Работа с байтами при помощи DataView
const dataView = new DataView(arrayBuffer);
const value = dataView.getInt16(0); // Считываем первые 2 байта как целое число
// Теперь у вас есть полный контроль над каждым байтом!
Визуализация
Представьте, что у вас есть поезд (ArrayBuffer
), где каждое купе соответствует байту:
🚂[🔲🔲🔲🔲] // 4-байтовый ArrayBuffer
Теперь мы вводим пассажиров (символы строки):
String ➡️ ArrayBuffer
"Data" // Строка преобразуется в физическую последовательность байтов
И в итоге получается:
🚂[🅓🅐🅣🅐]
На обратном пути:
ArrayBuffer ➡️ String
🚂[🔲🔲🔲🔲] // Процесс преобразования обратно в строку
И мы получаем:
"Data" // Строка восстановлена
Это наглядно демонстрирует переход данных из одной формы в другую при применении ArrayBuffer
.
Рекомендации и трюки преобразования
Мгновенное преобразование
Несмотря на то, что TextEncoder
и TextDecoder
являются стандартным решением, String.fromCharCode
в сочетании с типизированными массивами может быть использован для быстрых преобразований, особенно при работе с небольшими объемами данных.
// Быстрое преобразование ArrayBuffer в строку
const quickString = String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
// Быстрое преобразование строки в ArrayBuffer
const quickArrayBuffer = Uint8Array.from('Быстрые данные'.split(''), char => char.charCodeAt(0)).buffer;
// Это действительно быстрый вариант.
Обработка бинарных данных
Для работы с чисто бинарными данными лучше использовать объекты Blob
или представления ArrayBuffer
, поскольку TextEncoder
и String.fromCharCode
могут быть неоптимальными.
// Управляем бинарными данными
const byteArray = new Uint8Array(arrayBuffer);
// Теперь у вас полный контроль над данными.
Получение данных из внешних источников
При работе с бинарными данными, получаемыми по сети, нужно установить responseType
как 'arraybuffer'
, чтобы данные корректно отображались в требуемом формате.
//Запрос бинарных данных в формате ArrayBuffer
fetch('url', {
method: 'GET',
headers: new Headers({'Accept': 'application/octet-stream'}),
})
.then(response => response.arrayBuffer())
.then(buffer => {
//Вот и ваш ArrayBuffer!
});
Полезные материалы
- TextEncoder – Web API — Руководство по кодированию строк.
- ArrayBuffer – JavaScript — Работа с ArrayBuffer в JavaScript.
- TypedArray – JavaScript — Сведения о связи типизированных массивов с ArrayBuffer.
- Преобразование строк и ArrayBuffer – Stack Overflow — Обсуждение доступных методов преобразования.
- Buffer – Документация Node.js — Руководство по работе с Buffer в Node.js.