Как преобразовать Node.js Buffer в String
Объекты Buffer
Долгое время в JavaScript отсутствовала поддержка обработки массивов двоичных данных. Это изменилось с выходом ECMAScript 2015, когда были введены типизированные массивы, что позволило лучше обрабатывать такие случаи.
Все эти типы происходят от абстрактного класса TypedArray, каждый из которых специализируется на конкретных размерах многобайтовых целочисленных значений и знаках, а некоторые обеспечивают операции с плавающей точкой. Float64Array
, например, представляет собой массив 64-битных чисел с плавающей точкой; Int16Array
представляет собой массив 16-битных целочисленных значений со знаком.
Из всех типизированных массивов наиболее полезным, вероятно, является Uint8Array. Он позволяет обрабатывать двоичные данные, такие как файлы изображений, сетевые протоколы и потоковое видео, аналогично тому, как это делается в других языках программирования.
В мире Node.js есть ещё один класс Buffer, производный от Uint8Array
. Он добавляет некоторые служебные методы, такие как concat()
, allocUnsafe()
, compare()
, а так же методы для чтения и записи различных числовых типов, имитирующих то, что предлагает класс DataView (например, readUint16BE
, writeDoubleLE
и swap32
).
Кодировка текста
Тема кодирования текстовых символов с помощью компьютеров обширна и сложна, и я не буду вдаваться в неё в этой короткой статье.
Концептуально текст состоит из символов: мельчайших кусочков осмысленного содержания — обычно это буквы, но в зависимости от языка могут быть и другие, очень разные символы. Затем каждому символу присваивается кодовая точка: число, которое идентифицирует его во взаимно-однозначном (one-to-one) отношении.
Наконец, каждая кодовая точка может быть представлена последовательностью битов в соответствии с кодировкой. Кодировка — таблица, которая сопоставляет каждую кодовую точку с соответствующей битовой строкой.
Может показаться, что это простое сопоставление, но за последние десятилетия было создано несколько кодировок для соответствия многим компьютерным архитектурам и различным наборам символов.
Наиболее распространённая кодировка — ASCII.
Она включает в себя основные латинские символы (A-Z прописные и строчные буквы), цифры и множество знаков препинания, помимо некоторых управляющих символов. ASCII — это 7-битная кодировка, но компьютеры хранят данные в 8-битных блоках, называемых байтами, поэтому было создано множество 8-битных кодировок, расширяющих первые 128 символов ASCII ещё 128 специфичными для языков символами.
Очень распространённой кодировкой является ISO-8859-1, также известная под несколькими другими именами, такими как latin1
, IBM819
, CP819
и даже WE8ISO8859P1
. ISO-8859-1 добавляет некоторые дополнительные символы в ASCII и множество букв с диакритическими знаками, таких как Á, Ú, È и Õ.
Эти специфичные для языка кодировки работали достаточно хорошо в некоторых ситуациях, но с треском провалились в многоязыковых контекстах.
Потеря информации и повреждение данных были обычным явлением, поскольку программы пытались манипулировать текстом, используя неправильную кодировку файла.
Даже отображение содержимого файла было беспорядочным, потому, что текстовые файлы не включают имя кодировки, которая использовалась для кодирования его содержимого.
Пытаясь исправить это, в 1980-х годах был запущен стандарт Unicode. Его цель состоит в том, чтобы сопоставить каждый используемый в настоящее время символ в каждом человеческом языке (и некоторых исторических записях) с одной кодовой точкой.
Наиболее распространёнными кодировками Unicode являются UTF-16, UCS-2, UTF-32, и UTF-8. За исключением UCS-2, который использует фиксированную ширину для всех кодовых точек (таким образом предотвращая представление всех символов Unicode), все эти кодировки используют переменное количество бит для кодирования каждой кодовой точки.
В Интернете наиболее широко используемой кодировкой Unicode является UTF-8, поскольку она достаточно эффективна для многих случаев. Она использует 1 байт для символов ASCII и 2 байта для большинства Европейских и Ближневосточных языков — но менее эффективная для Азиатских языков требующих 3 байта и более. Например, французская поговорка Il vaut mieux prévenir que guérir
эквивалентна следующей последовательности байт, если она закодирована с использованием UTF-8 (байты показаны в шестнадцатеричном формате):
Il vaut mieux prévenir que guérir
49
, 6c
, 20
, 76
, 61
, 75
, 74
, 20
, 6d
, 69
, 65
, 75
, 78
, 20
, 70
, 72
, c3 a9
, 76
, 65
, 6e
, 69
, 72
, 20
, 71
, 75
, 65
, 20
, 67
, 75
, c3 a9
, 72
, 69
, 72
Преобразование Buffer в String Node.js
Сказав всё это, содержимое 'Buffer' можно быстро преобразовать в строку с помощью метода 'toString()':
const b = Buffer.from([101, 120, 97, 109, 112, 108, 101]);
console.log(b.toString()); // example
Помните ту речь о текстовых кодировках? Что ж, класс Buffer
по умолчанию использует UTF-8 при преобразовании в/из строк, но вы также можете выбрать другую из небольшого набора поддерживаемых кодировок:
const b = Buffer.from([101, 120, 97, 109, 112, 108, 101]);
console.log(b.toString('latin1')); // example
В большинстве случаев UTF-8 лучший вариант как для чтения, так и для записи. Но для полноты, вот полный список поддерживаемых кодировок в Node.js (по состоянию на сентябрь 2021 г.) — имена не чувствительны к регистру:
Кодировка | Принятый псевдоним |
---|---|
ascii | |
base64 | |
base64url | |
hex | |
latin1 | binary |
ucs2 | ucs-2 |
utf8 | utf-8 |
utf16le | utf-16le |
Преобразование Node.js String в Buffer
Так же возможно преобразование данных в обратном направлении. Начнём со строки, из неё можно создать новый Buffer
(если кодировка не указана, Node.js предполагает UTF-8):
const s = Buffer.from('example', 'utf8');
console.log(s); // <Buffer 65 78 61 6d 70 6c 65>
Если вам нужно записать текст в существующий объект Buffer
, вы можете использовать метод write()
:
const b = Buffer.alloc(10);
console.log(b);
// <Buffer 00 00 00 00 00 00 00 00 00 00>
b.write('example', 'utf8');
console.log(b);
// <Buffer 65 78 61 6d 70 6c 65 00 00 00>
Вы даже можете установить начальную позицию (смещение):
const b = Buffer.alloc(10);
b.write('test', 4, 'utf8');
console.log(b);
// <Buffer 00 00 00 00 74 65 73 74 00 00>
Заключение
Короче говоря, объект Buffer
легко преобразовать в строку с помощью метода toString()
. Обычно вам нужна кодировка по умолчанию UTF-8, но при необходимости можно указать другую. Чтобы преобразовать строку в объект Buffer
, используйте статический метод Buffer.from()
— опять же, необязательно передавать кодировку.
Вопросы и ответы
Вопрос: Является ли Buffer
строкой?
Строка — это последовательность символов, а Buffer
это последовательность байт. Несмотря на то, что Buffer
может содержать закодированное содержимое строкового значения, он также может кодировать другие типы значений или любые двоичные данные.
Вопрос: Что делает Buffer
в Node.js?
Buffer
позволяет хранить массивы байт и манипулировать ими, особенно при работе с файлами: такие функции, как fs.readFile
, возвращают объекты Buffer
при чтении двоичных файлов. Также важно, чтобы функции обрабатывали сетевые коммуникации и обработку изображений.
Вопрос: Что такое объект Buffer
в программировании?
Объект Buffer
— это способ абстрагирования последовательностей или массивов байт. Помимо обычных операций с массивами, таких как получение и изменение одного или нескольких элементов массива байт, Buffer
обычно имеет расширенные методы для чтения и записи более сложных значений, таких как целые числа, числа с плавающей точкой и строки.