Модуль Buffer
Цель
Ознакомится с модулем Buffer и его основными методами.
Предварительныетребования
Установленны Node.js и npm
Умение работать с модулями Node.js
Введение
Язык JavaScript сам по себе содержит только строковый тип данных, и не содержит двоичного типа данных.
Но при работе с такими потоками, как поток TCP или файлами, вы должны использовать двоичные данные. Таким образом, в Node.js был определен класса Buffer, который используется для создания какого-либо специального буфера для хранения двоичных данных.
Класс Buffer используется для хранения данных и позволяет Node.js обрабатывать двоичные данные. Всякий раз, когда вам нужно обрабатывать операции ввода/вывода для перемещения данных Node.js будет использовать библиотеку буфера, при этом исходные данные хранятся в экземпляре класса Buffer.
Экземпляры класса Buffer похожи на массивы целых чисел, однако соотносятся с фиксированным, сырым распределением памяти вне движка V8. Размер для экземпляров Buffer устанавливается в процессе создания и не может быть изменен.
Класс Buffer является глобальным в Node.js, поэтому его можно не подключать с помощью командыrequire(‘buffer’)
.
Создание экземпляра
Исторически сложилось так, что экземпляры Buffer создавались с помощью конструктораBuffer
, который распределяет возвращаемый Buffer по-разному, основываясь на заданных аргументах:
- Если первому аргументу
Buffer()
передается число (например,new Buffer(10)
), то создается новый объект буфера заданного размера. До версии 8.0 память для каждого экземпляра буфера выделялась, но не заполнялась и ее приходилось заполнять вручную. Такое поведение является предусмотренным для того, чтобы повысить производительность, однако, опыт разработки показывает, что есть явное различие между созданием быстрого, но не инициализированного буфера и созданием медленного, но безопасного. - Если первому аргументу передается строка, массив или буфер, то переданные объекты копируются в буфер.
ArrayBuffer
в качестве аргумента возвращаетBuffer
, который разделяет выделенную память с данным буфером массива.
Так как поведение new Buffer()
существенно изменяется в зависимости от задаваемого первого аргумента, приложения, которые не проверяют точно входящие аргументы, передаваемые в new Buffer()
, или те, которые не могут должным образом инициализировать новое содержимое буфера, могут поставить под угрозу безопасность и надежность кода.
Для того, чтобы сделать процесс создания объектов более надежным и менее склонным к ошибкам были представленны новые способы создания экземпляров:
- Buffer.from(array) возвращает новый буфер, содержащий копию существующих данных.
Buffer.from(arrayBuffer[, byteOffset[, length]]) возвращает новые буфер, который делится выделенной памятью с
ArrayBuffer
.Buffer.from(buffer) возвращает новый буфер, содержащий копию содержимого данного буфера.
Buffer.from(string[, encoding]) возвращает новый буфер, содержащий копию заданной строки.
Buffer.alloc(size[, fill[, encoding]]) возвращает «заполненный» экземпляр буфера заданного размера. Этот метод может быть существенно медленнее, чем
Buffer.allocUnsafe(size)
, но обеспечивает то, что новосозданный буфер не будет содержать старые или потенциально незащищенные данные.Buffer.allocUnsafe(size) возвращает новый буфер заданного размера, чье содержимое должно быть инициализировано с помощью
buff.fill(0)
или полностью написано вручную.
Запись в буфер
Для записи в буфер используется метод [buf.write(string[, offset[, length]][, encoding])](https://nodejs.org/dist/latest-v8.x/docs/api/buffer.html#buffer_buf_write_string_offset_length_encoding), при этом если кодировка не заданна, то по умолчанию используется 'utf-8'. Так же есть специальные методы для записи в определенном, числовом формате, например:
Метод | Описание |
---|---|
buf.writeInt8(value, offset[, noAssert]) | Записывает value в буфер при заданном смещении. Аргумент value должен быть валидным знаковым 8-битным целым числом. |
buf.writeDoubleLE(value, offset[, noAssert]) | Записывает value в буфер при заданном смещении с указанным endian форматом (writeDoubleBE() записывает big-endian, writeDoubleLE() – little-endian). Аргумент value должен быть валидным 64-битным числом типаdouble. |
buf.writeFloatBE(value, offset[, noAssert]) | Записывает value в буфер при заданном смещении с указанным endian форматом (writeFloatBE() записывает big-endian, writeFloatLE() – little-endian). Аргумент value должен быть валидным 32-битным числом типа float. |
buf.writeIntLE(value, offset, byteLength[, noAssert]) | Записывает value в буфер при заданном смещении и byteLength. Поддерживает точность до 48 бит. |
buf.writeUInt8(value, offset[, noAssert]) | Записывает value в буфер при заданном смещении. Аргумент value должен быть валидным беззнаковым 8-битным целым числом. |
Чтение из буфера
Для чтения данных из буфера в произвольной кодировке используется метод buf.toString([encoding[, start[, end]]]). По умолчанию также используется кодировка 'utf-8'. Также есть методы для чтения уже в определенном формате.
Метод | Описание |
---|---|
buf.readInt8(offset[, noAssert]) | Считывает value в буфер при заданном смещении. Аргумент value должен быть валидным знаковым 8-битным целым числом. |
buf.readDoubleLE(offset[, noAssert]) | Считывает 64-битное число типаdoubleиз буфера при заданном смещении с указанным endian форматом (readDoubleBE() возвращает big-endian, readDoubleLE() возвращает little-endian) |
buf.readFloatLE(offset[, noAssert]) | Считывает 32-битное число типаfloatиз буфера при заданном смещении с указанным endian форматом (readFloatBE() возвращает big-endian, readFloatLE() возвращает little-endian) |
buf.readIntBE(offset[, noAssert]) | Считывает количество байт byteLength из буфера при заданном смещении и интерпретирует результат как пару взаимозаменяемых значений. Подерживает точность до 48 бит. |
buf.readUInt8(offset[, noAssert]) | Считывает 8-битное беззнаковое число типа integer из буфера при заданном смещении. |
Для определения длины буффера используется функция buf.length
Практическое задание
Создайте буффер, передав числовой массив. С помощью метода buf.writeInt8 допишите значения и вывидите с помощью buf.readInt8 полученный буфер на консоль.
Глоссарий
Термин | Значение |
---|---|
Движок V8 | Движок JavaScript с открытым программным кодом, распространяемый по лицензии BSD. Разработан датским отделением компании Google. |
Big-endian | Порядок от старшего к младшему (англ. big-endian — большим концом) соответствует привычному порядку записи арабских цифр, например, число сто двадцать три было бы записано при таком порядке как 123. В этом же порядке принято записывать байты в технической и учебной литературе, если другой порядок явно не обозначен. Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому порядок байтов от старшего к младшему часто называют «сетевым порядком байтов» (англ. network byte order). |
Little-endian | Порядок от младшего к старшему (англ. little-endian — малым концом) - Это обратный порядок по отношению к привычному порядку записи арабских цифр, например, число сто двадцать три было бы записано при таком порядке как 321. Этот порядок записи принят в памяти персональных компьютеров с процессорами архитектуры x86, в связи с чем иногда его называют интеловский порядок байтов. |