2016-06-13 2 views
2

В node.js У меня есть буфер (он был сохранен как blob в mysql и получен с использованием sequelize) Я знаю, что этот буфер представляет собой массив из 16-битных целых чисел. Раньше я разбирал код с циклом for.Node.js буфер для типизированного массива

var spectrum_buffer = spectrums[idx]["spectrum"];//this is a buffer 
    var parsed_spectrum = []; 
    for (var i = 0; i < spectrum_buffer.length/2; i++) { 
     parsed_spectrum[i] = spectrum_buffer.readInt16BE(i * 2); 
    } 

Я читал, что readInt16BE медленно и теперь, что есть typedarrays для arraybuffers. (которые отличаются от буферов). Есть ли лучший способ создания массива из этого буфера.

Update 1

На основе обратной связи я сделал следующее

var arr = new Int16Array(spectrum.buffer) 

Который дает мне соответствующий тип, однако байты становятся поменяны местами. Буфер спектра хранится в большом конце.

< Буферные e1 d7 e0 b9 e3 52 е2 d5 е2-е изд е2 92 е2 d 6 е2 97 е3 04 е1 95 е1 е2> е1 d8 е3 14 е2 FD е1 изд е2 d3 е3 09 e1 9f e2 14 e2 f2 е2 54 e2 e2 1f 54> e2 06 e2 8а ...>

первые три цифры встретив как -10271, -17952, 21219

Однако они не должны меняться, что многое, и все три должны быть отрицательным.

Первый номер должен быть -7721 (двойки дополнение всегда путает меня)

Так что делает Int16Array на узле 6 предположим большой Endian или Little Endian и как я могу справиться с этим.

+0

Примечание: https://nodejs.org/api /buffer.html#buffer_buffers_and_typedarray Конечно, похоже, что это возможно, если вы создаете типизированный массив * до * заполнения буфера. –

+0

Просто, чтобы вы знали, я обновил свой ответ.Существует еще более низкий уровень интерфейса, который вы можете использовать, если вам нужно прочитать данные с определенной энтерианностью. –

ответ

1

Несомненно. Буферы Node.js are a special instance из Uint8Array.

Так что, если вы хотите создать экземпляр Int16Array вы можете создать копию буфера:

var int16Arr = new Int16Array(spectrum_buffer); 

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

var int16Arr = new Int16Array(spectrum_buffer.buffer); 

Обновление:

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

A DataView - это оболочка вокруг буфера, которая дает вам полный контроль над доступом к этим данным. В вашем случае, вы хотели бы использовать метод getInt16 и установить флаг порядок байтов, сколько необходимо для данных:

var littleEndian = true; // or false, depends on your needs 
var dataView = new DataView(spectrum.buffer); 
dataView.getInt16(offset, littleEndian); 
0

Попробуйте это:

//this is a buffer 
var spectrum_buffer = spectrums[idx]["spectrum"]; 

// these two views share same memory 
var int16view = new Int16Array(spectrum_buffer); 
var uint8view = new Uint8Array(spectrum_buffer); 

var parsed_spectrum = []; 

for (var i = 0; i < int16view.length; i++) { 
    // swap byte order 
    [uint8view[i*2], uint8view[i*2+1]] = [uint8view[i*2+1], uint8view[i*2]]; // ES6 swap 
    // read swapped bytes as Int16 
    parsed_spectrum[i] = int16view[i]; 
} 
Смежные вопросы