2016-06-13 101 views
2

在node.js中,我有一個緩衝區(它被存儲爲一個blob在mysql中,並使用sequelize檢索) 我知道這個Buffer是一個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。 (這與緩衝區不同)。有沒有更好的方法從這個緩衝區創建一個int數組。

更新根據反饋我做了以下

var arr = new Int16Array(spectrum.buffer) 

這給了我相應的類型,不過字節越來越交換1

。頻譜緩衝區以大端存儲。

<緩衝E1 D7的e0 B9 E3 52 E2 D5 E2編E2 92 E2 D6 E2 97 E3 04 E1 95 E1 E2> E1 D8 E3 14 E2 FD E1編E2 D3 E3 09 E1 9F E2 14個E2 F2 E2 54 E2 1F E2 54> E2 06 E2 8A ...>

的前三個數字正在說爲-10271,-17952,21219

但是他們不應該改變那麼多,並且所有三個應該是負面的。

第一個數字應爲-7721(二進制補碼總是讓我困惑)

所以確實Int16Array節點6採用大尾數法或小尾數,如何處理這個問題。

+0

注:https://nodejs.org/api在你的情況,根據需要爲您的數據,你會想使用getInt16方法並設置字節順序標誌/buffer.html#buffer_buffers_and_typedarray看起來好像是可能的,如果你在填充緩衝區之前創建類型化數組*。 –

+0

就這麼你知道,我更新了我的答案。如果您需要讀取具有特定字節數的數據,則可以使用更低級別的接口。 –

回答

1

當然。 Node.js緩衝區are a special instanceUint8Array

所以,如果你想創建一個Int16Array的實例,你可以創建緩衝區的副本:

var int16Arr = new Int16Array(spectrum_buffer); 

或創建一個新的陣列引用相同的底層緩衝,這意味着你不必複製所有數據:

var int16Arr = new Int16Array(spectrum_buffer.buffer); 

更新:

類型數組默認使用本地字節順序。如果您需要指定字節順序,則可以使用較低級別的接口:DataView

A DataView是一個緩衝區的包裝,它使您可以完全控制數據的訪問方式。

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]; 
}