Интерпретация буфера Node.js

Node.js внешний интерфейс JavaScript Medium

Что такое буфер?

Buffer существует как глобальный объект и может использоваться без введения модуля, игнорировать его нельзя. Можно понять, что Буфер — это область памяти, открытая для хранения двоичных данных. То, что открывает Buffer, — это память вне кучи.

Каковы сценарии применения Buffer?

поток

Как понять течение? Поток представляет собой набор данных (аналогично данным и строкам), но данные потока нельзя получить за один раз, и данные не будут загружены в память, поэтому поток очень подходит для обработки больших данных и внешние источники, которые периодически возвращают фрагменты. Скорость между производителем и потребителем потока обычно несовместима, поэтому для временного хранения некоторых данных необходим буфер. Размер буфера задается параметром highWaterMark, который по умолчанию равен 16 КБ.

Хранение данных, требующих много памяти

Объем памяти, занимаемый объектом Buffer, не учитывается в ограничении объема памяти процесса Node.js, поэтому его можно использовать для хранения больших объектов, но размер объекта по-прежнему ограничен. В нормальных условиях 32-разрядная система занимает около 1 ГБ, а 64-разрядная система — около 2 ГБ.

Как создать буфер

В дополнение к автоматическому и неявному созданию буферов потоками, буферы также можно создавать вручную следующим образом:

Данные, хранящиеся в буфере, были определены

Buffer.from(obj) // obj поддерживает типы string, buffer, arrayBuffer, array или массивоподобный объект

Примечание. Buffer.from не поддерживает передачу чисел, например:

Buffer.from(1234);

buffer.js:208
    throw new errors.TypeError(
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "value" argument must not be of type number. Received type number
    at Function.from (buffer.js:208:11)
    ...
    

Чтобы передать числа, вы можете передать массив:

const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf); //  <Buffer 01 02 03 04>

Но с этим методом есть проблема, при сохранении разных значений бинарные данные, записанные в буфер, будут одинаковыми, как показано ниже:

const buf2 = Buffer.from([127, -1]);
console.log(buf2);     // <Buffer 7f ff>

const buf3 = Buffer.from([127, 255]);
console.log(buf3);    // <Buffer 7f ff>

console.log(buf3.equals(buf2));  // true

Когда все записываемые числа попадают в диапазон от 0 до 255 (readUInt8 для чтения) или все попадают в диапазон от -128 до 127 (readInt8 для чтения), тогда проблем нет, в противном случае это сильно не рекомендуется использовать Buffer.from для сохранения набора чисел. Потому что при чтении разных методов должны вызываться разные числа.

Данные буферного хранилища не определены

Buffer.alloc, Buffer.allocUnsafe, Buffer.allocUnsafeSlow

Buffer.alloc заполнит выделенную память значением 0, поэтому он медленнее, чем два последних, но и безопаснее. Конечно, вы также можете использовать флаг --zero-fill-buffers, чтобы allocUnsafe и allocUnsafeSlow также заполнялись 0 значениями после выделения памяти.

node --zero-fill-buffers index.js

Когда выделенное пространство меньше 4 КБ, allocUnsafe напрямую выделяет пространство из предварительно выделенного буфера, поэтому скорость выше, чем у allocUnsafeSlow.Когда он больше или равен 4 КБ, скорость обоих одинакова.

// 分配空间等于4KB
function createBuffer(fn, size) {
  console.time('buf-' + fn);
  for (var i = 0; i < 100000; i++) {
    Buffer[fn](size);
  }
  console.timeEnd('buf-' + fn);
}
createBuffer('alloc', 4096);
createBuffer('allocUnsafe', 4096);
createBuffer('allocUnsafeSlow', 4096);

// 输出
buf-alloc:           294.002ms
buf-allocUnsafe:     224.072ms
buf-allocUnsafeSlow: 209.22ms
function createBuffer(fn, size) {
  console.time('buf-' + fn);
  for (var i = 0; i < 100000; i++) {
    Buffer[fn](size);
  }
  console.timeEnd('buf-' + fn);
}
createBuffer('alloc', 4095);
createBuffer('allocUnsafe', 4095);
createBuffer('allocUnsafeSlow', 4095);
// 输出
buf-alloc:           296.965ms
buf-allocUnsafe:     135.877ms
buf-allocUnsafeSlow: 205.225ms

Следует помнить одну вещь: новый метод Buffer(xxxx) устарел.

Использование буфера

буфер в строку

const buf = Buffer.from('test');
console.log(buf.toString('utf8'));                 // test
console.log(buf.toString('utf8', 0, 2));           // te

буфер в json

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
console.log(buf.toJSON());    // { type: 'Buffer', data: [ 1, 2, 3, 4, 5 ] }

Отсечение буфера, новый буфер, возвращенный после отсечения, указывает на ту же память, что и исходный буфер.

buf.slice([start[, end]])
start 起始位置
end 结束位置(不包含)

示例:

var buf1 = Buffer.from('test');
var buf2 = buf1.slice(1, 3).fill('xx');
console.log("buf2 content: " + buf2.toString()); // xx
console.log("buf1 content: " + buf1.toString()); // txxt

Буферная копия, буфер отличается от массива, длина буфера не изменится после его определения, поэтому, когда скопированный исходный буфер больше целевого буфера, будет скопирована только часть значения.

buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])

示例:
var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('ABCDEF');

buf1.copy(buf2, 1);
console.log(buf2.toString()); //Abcdef

Суждение о равенстве буфера, сравнение является двоичным значением

buf.equals(otherBuffer)

示例:
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex'); 
console.log(buf1.equals(buf2));    // true

В дополнение к равенству, сравнение также может использоваться для определения равенства (когда результат равен 0, оно равно), но основная функция сравнения заключается в сортировке экземпляров буфера в массиве.

содержит ли буфер определенное значение

buf.includes(value[, byteOffset][, encoding])
buf.indexOf(value[, byteOffset][, encoding])

示例:
const buf = Buffer.from('this is a buffer');
console.log(buf.includes('this'));  // true
console.log(buf.indexOf('this'));  // 0

записать прочитанное значение

Способ написания:

И фиксированное количество битов более одного байта: write{Double| Float | Int16 | Int32| UInt16 | UInt32 }{BE|LE}(value, offset)

Количество цифр не фиксировано:write{Int | UInt}{BE | LE}(value, offset, bytelength) // Этот метод обеспечивает более гибкое количество битов для представления данных (например, 3 бита, 5 битов)

Количество битов фиксировано и равно 1 байту: write{Int8 | Unit8}(value, offset)

Метод чтения:

Фиксированное количество бит и более 1 байта:читать {двойной | поплавок | int16 | int32 | uint16 | uint32} {be | le} (смещение)

Количество цифр не фиксировано: read{Int | UInt}{BE | LE}(offset, byteLength)

Количество битов фиксировано и равно 1 байту: read{Int8 | Unit8}(offset)

Double, Float, Int16, Int32, UInt16, UInt32 не только определяют количество цифр, характеризующих число, но и определяют, включены ли отрицательные числа, поэтому они определяют разные диапазоны данных. В то же время, поскольку количество цифр, представляющих число, превышает 8, оно не может быть представлено одним байтом, поэтому оно связано с различием порядка байтов компьютера (порядок байтов с прямым порядком байтов и порядок байтов с прямым порядком байтов)

Разницу между прямым порядком байтов и прямым порядком байтов можно понять следующим образом: старшее значение значения находится в начальной позиции буфера, а начальная позиция младшего буфера значения — с прямым порядком байтов. .

const buf = Buffer.allocUnsafe(2);
buf.writeInt16BE(256, 0)  
console.log(buf);           // <Buffer 01 00> 
buf.writeInt16LE(256, 0)
console.log(buf);           // <Buffer 00 01>

https://tool.lu/hexconvert/ Здесь вы можете просмотреть преобразование между различными основаниями значения.Если это прямой порядок байтов, вы можете напрямую сплайсировать шестнадцатеричный порядок (0100).Если это прямой порядок байтов, он должен быть обменян Следующий порядок является правильным представлением.

буферное слияние

Buffer.concat(list[, totalLength]) //totalLength不是必须的,如果不提供的话会为了计算totalLength会多一次遍历

const buf1 = Buffer.from('this is');
const buf2 = Buffer.from(' funny');
console.log(Buffer.concat([buf1, buf2], buf1.length + buf2.length));
// <Buffer 74 68 69 73 20 69 73 20 66 75 6e 6e 79>

очистить буфер

Самый быстрый способ очистить данные буфера — это buffer.fill(0)

Связь между модулем буфера и буфером

Буфер — это ссылка на глобальную глобальную переменную, которая указывает на буфер.

 const buffer = require('buffer');
 console.log(buffer.Buffer === Buffer); //true

В модуле буфера есть другие свойства и методы.

const buffer = require('buffer');
console.log(buffer);
{ Buffer:
   { [Function: Buffer]
     poolSize: 8192,
     from: [Function: from],
     alloc: [Function: alloc],
     allocUnsafe: [Function: allocUnsafe],
     allocUnsafeSlow: [Function: allocUnsafeSlow],
     isBuffer: [Function: isBuffer],
     compare: [Function: compare],
     isEncoding: [Function: isEncoding],
     concat: [Function: concat],
     byteLength: [Function: byteLength],
     [Symbol(node.isEncoding)]: [Function: isEncoding] },
  SlowBuffer: [Function: SlowBuffer],
  transcode: [Function: transcode],
  INSPECT_MAX_BYTES: 50,
  kMaxLength: 2147483647,
  kStringMaxLength: 1073741799,
  constants: { MAX_LENGTH: 2147483647, MAX_STRING_LENGTH: 1073741799 } }

Приведенные выше kMaxLength и MAX_LENGTH представляют максимальный размер памяти при создании нового буфера, и при превышении предельного значения будет сообщено об ошибке.

32 на машине(2^30)-1(~1GB)

Да на 64-битных машинах(2^31)-1(~2GB)

Освобождение буфера

Мы не можем вручную собрать экземпляр буфера, мы можем полагаться только на V8, единственное, что мы можем сделать, это разыменовать экземпляр буфера.

использованная литература

Шина Лулу.GitHub.IO/Linux/Чара…

Вууху. Руань Ифэн.com/blog/2007/1…

medium.free код camp.org/do-yes-thousands…

Ууууууууууу Баррета com/blog/2017/0…

средний.бесплатный код camp.org/node-just-str…

woooooooooooooooooooooooooo.com/node будет / узел ...