Как я могу преобразовать двоичный буфер NodeJS в JavaScript ArrayBuffer?
javascript
node.js
binary
buffer
arraybuffer
Дрейк Амара
источник
источник
Array
. Итак, чтобы хранить много чисел с плавающей запятой, вам нужноFloat32Array
4 байта. И если вам нужна быстрая сериализация этих поплавков в файл, который вам нуженBuffer
, так как сериализация в JSON занимает много времени.Ответы:
Экземпляры
Buffer
также являются экземплярамиUint8Array
в node.js 4.x и выше. Таким образом, наиболее эффективным решением являетсяbuf.buffer
прямой доступ к свойству в соответствии с https://stackoverflow.com/a/31394257/1375574 . Конструктор Buffer также принимает аргумент ArrayBufferView, если вам нужно пойти в другом направлении.Обратите внимание, что это не создаст копию, а это означает, что запись в любой ArrayBufferView будет записывать в исходный экземпляр Buffer.
В более старых версиях node.js содержал ArrayBuffer как часть v8, но класс Buffer предоставляет более гибкий API. Чтобы читать или писать в ArrayBuffer, вам нужно только создать представление и скопировать его.
Из буфера в ArrayBuffer:
От ArrayBuffer к Buffer:
источник
size&0xfffffffe
скопируйте 32-битные целые числа, затем, если остался 1 байт, скопируйте 8-битное целое число, если 2 байта, скопируйте 16-битное целое число, а если 3 байта, скопируйте 16-битное и 8-битное целое число.ab
возвращается? Ничего не поделаешьab
? Я всегда получаю{}
в результате.slice()
Метод возвращает новый объектArrayBuffer
, содержимое которого является копиейArrayBuffer
байтов this от начала, включительно, до конца, исключая». - MDNArrayBuffer.prototype.slice()
Без зависимостей, самый быстрый, Node.js 4.x и новее
Buffer
s естьUint8Array
s, поэтому вам просто нужно разрезать (скопировать) его область подложкиArrayBuffer
.Материал
slice
и смещение требуется, потому что маленькиеBuffer
s (по умолчанию менее 4 КБ, половина размера пула ) могут быть представлениями на общем ресурсеArrayBuffer
. Без нарезки вы можете получитьArrayBuffer
данные из другогоBuffer
. См. Объяснение в документации .Если вам в конечном итоге понадобится
TypedArray
, вы можете создать его, не копируя данные:Никаких зависимостей, умеренная скорость, любая версия Node.js
Используйте ответ Мартина Томсона , который выполняется за время O (n) . (См. Также мои ответы на комментарии к его ответу о неоптимизации. Использование DataView происходит медленно. Даже если вам нужно перевернуть байты, есть более быстрые способы сделать это.)
Зависимость, быстро, Node.js ≤ 0,12 или iojs 3.x
Вы можете использовать https://www.npmjs.com/package/memcpy, чтобы двигаться в любом направлении (от буфера до ArrayBuffer и обратно). Это быстрее, чем другие ответы, опубликованные здесь, и это хорошо написанная библиотека. Узлы от 0.12 до iojs 3.x требуют форка ngossen (см. Это ).
источник
.byteLength
и.byteOffset
документированы?var ab = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
спас мой день«От ArrayBuffer до Buffer» можно сделать так:
источник
Более быстрый способ написать это
Однако, похоже, что он работает примерно в 4 раза медленнее, чем предлагаемая функция toArrayBuffer в буфере с 1024 элементами.
источник
Buffer
также являются экземплярамиUint8Array
в Node.js 4.x и выше. Для более низких версий Node.js вы должны реализоватьtoArrayBuffer
функцию.1. А
Buffer
- это просто вид для изученияArrayBuffer
.
📜 Node.js 9.4.0Buffer
, По сути, представляет собойFastBuffer
, которыйextends
(наследует от)Uint8Array
, который представляет собой октет-блок вид ( «частичный аксессор») от фактической памяти, сArrayBuffer
./lib/buffer.js#L65-L73
2. Размер
ArrayBuffer
и размер его вида могут различаться.Причина № 1:
Buffer.from(arrayBuffer[, byteOffset[, length]])
.С помощью
Buffer.from(arrayBuffer[, byteOffset[, length]])
, вы можете создатьBuffer
с указанием его основыArrayBuffer
и позиции и размера представления.Причина № 2:
FastBuffer
выделение памяти.Он распределяет память двумя различными способами в зависимости от размера.
ArrayBuffer
который точно соответствует требуемой памяти./lib/buffer.js#L306-L320
📜 Node.js 9.4.0/lib/buffer.js#L98-L100
Что вы подразумеваете под « пул памяти ?»
Пул памяти является фиксированным размером предварительно выделен блоком памяти для хранения кусков памяти малого размера для
Buffer
с. Его использование обеспечивает плотное соединение небольших блоков памяти, что предотвращает фрагментацию. вызванную раздельным управлением (выделением и освобождением) блоков памяти малого размера.В этом случае используются пулы памяти
ArrayBuffer
с размером по умолчанию 8 КиБ, который указан вBuffer.poolSize
. Когда он должен предоставить блок памяти небольшого размера для aBuffer
, он проверяет, имеет ли последний пул памяти достаточно доступной памяти для обработки этого; если это так, он создает объект,Buffer
который «просматривает» данный частичный фрагмент пула памяти, в противном случае он создает новый пул памяти и так далее.Вы можете получить доступ к основному
ArrayBuffer
изBuffer
. ВBuffer
«Sbuffer
свойство (то есть, унаследованное отUint8Array
) удерживает его. «Небольшой» «s свойство является , который представляет весь пул памяти. Так что в этом случае размер и меняется.Buffer
buffer
ArrayBuffer
ArrayBuffer
Buffer
3. Поэтому нам нужно извлечь память, которую он « просматривает ».
ArrayBuffer
Фиксируется в размерах, так что мы должны извлечь его, сделав копию части. Для этого мы используемBuffer
«ю.ш.byteOffset
имущество иlength
имущество , которые наследуются отUint8Array
и наArrayBuffer.prototype.slice
метод , который делает копию частиArrayBuffer
. Методslice()
-ing здесь был вдохновлен @ZachB .4. Улучшение производительности
Если вы хотите использовать результаты только для чтения или если вы можете изменить
Buffer
содержимое входных данных , вы можете избежать ненужного копирования в память.источник
obtain_arraybuffer
:buf.buffer.subarray
не существует. Вы имели в видуbuf.buffer.slice
здесь?ArrayBuffer.prototype.slice
а затем изменил егоUint8Array.prototype.subarray
. О, и я сделал это неправильно. Наверное, немного запутался тогда. Сейчас все хорошо благодаря тебе.Используйте следующий превосходный пакет NPM:
to-arraybuffer
.Или вы можете реализовать это самостоятельно. Если ваш буфер вызывается
buf
, сделайте это:источник
Вы можете думать
ArrayBuffer
как о набранныхBuffer
.ArrayBuffer
Поэтому всегда нужен тип (так называемый «Array Buffer View»). Как правило, Array Buffer View имеет типUint8Array
илиUint16Array
.Есть хорошая статья от Ренато Манджини о преобразовании между ArrayBuffer и String .
Я суммировал основные части в примере кода (для Node.js). Также показано, как конвертировать между типизированным
ArrayBuffer
и нетипизированнымBuffer
.источник
Я попытался выше для Float64Array, и он просто не работал.
Я понял, что на самом деле данные должны быть прочитаны «INTO» в виде правильных кусков. Это означает чтение 8 байтов за раз из исходного буфера.
Во всяком случае, это то, что я закончил ...
источник
Buffer.read*
методы все медленно, также.Этот прокси будет представлять буфер как любой из TypedArrays, без какой-либо копии. :
https://www.npmjs.com/package/node-buffer-as-typedarray
Он работает только на LE, но может быть легко перенесен на BE. Кроме того, никогда не проверял, насколько это эффективно.
источник
Теперь для этого есть очень полезный пакет npm:
buffer
https://github.com/feross/bufferОн пытается предоставить API, который на 100% идентичен Buffer API узла и позволяет:
и еще немного.
источник
NodeJS, в какой-то момент (я думаю, это был v0.6.x) была поддержка ArrayBuffer. Я создал небольшую библиотеку для base64 кодирования и декодирования здесь , но так как обновление до v0.7, тесты (на NodeJS) терпят неудачу. Я думаю о создании чего-то, что нормализует это, но до тех пор, я полагаю,
Buffer
должен использоваться нативный нод.источник
Я уже обновил свой узел до версии 5.0.0, и я работаю с этим:
Я использую его для проверки образа моего VHD-диска.
источник
toArrayBuffer(new Buffer([1,2,3]))
->['01', '02', '03']
- это возвращает массив строк, а не целые числа / байты.