2015-11-13 84 views
7

Javascript ArrayBuffer或TypedArrays沒有任何類型的appendByte(),appendBytes()或appendBuffer()方法。所以如果我想一次填充一個ArrayBuffer的一個值,我該怎麼做?如何將字節,多字節和緩衝區添加到JavaScript中的ArrayBuffer?

var firstVal = 0xAB;    // 1 byte 
var secondVal = 0x3D7F   // 2 bytes 
var anotherUint8Array = someArr; 

var buffer = new ArrayBuffer(); // I don't know the length yet 
var bufferArr = new UInt8Array(buffer); 

// following methods do not exist. What are the alternatives for each?? 
bufferArr.appendByte(firstVal); 
bufferArr.appendBytes(secondVal); 
bufferArr.appendBuffer(anotherUint8Array); 
+0

它是一個數組,使用數組語法'r [i] = x'例如:https://github.com/rndme/download/blob/master/download.js#L69也查看Uint8Array構造函數的語法: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array#Syntax - 你需要在該陣列緩衝區上的大小,以便能夠像那樣使用它...... – dandavis

+1

你創建後無法修改緩衝區大小 –

回答

8

您可以創建一個新的TypedArray用新ArrayBuffer,但你不能改變現有的緩衝區的大小

function concatTypedArrays(a, b) { // a, b TypedArray of same type 
    var c = new (a.constructor)(a.length + b.length); 
    c.set(a, 0); 
    c.set(b, a.length); 
    return c; 
} 

現在能做

var a = new Uint8Array(2), 
    b = new Uint8Array(3); 
a[0] = 1; a[1] = 2; 
b[0] = 3; b[1] = 4; 
concatTypedArrays(a, b); // [1, 2, 3, 4, 0] Uint8Array length 5 

如果您想使用不同類型,請通過Uint8Array作爲最小單位是字節,即

function concatBuffers(a, b) { 
    return concatTypedArrays(
     new Uint8Array(a.buffer || a), 
     new Uint8Array(b.buffer || b) 
    ).buffer; 
} 

這意味着.length會按預期工作,你現在可以將此轉換爲您鍵入的選擇陣列(請確保它是會接受緩衝區的.byteLength雖然A型)


從這裏開始,您現在可以實現您喜歡的任何連接數據的方法,例如

function concatBytes(ui8a, byte) { 
    var b = new Uint8Array(1); 
    b[0] = byte; 
    return concatTypedArrays(ui8a, b); 
} 

var u8 = new Uint8Array(0); 
u8 = concatBytes(u8, 0x80); // [128] 
+0

感謝@Paul S.如果將這些基本功能作爲規範的一部分並在本地實現,本來是不錯的,但是您的解決方案非常好。我仍然有一個問題,你將如何附加一個多字節,可以說一個4字節的值給一個類型數組。我們可以循環併爲每個單字節多次調用你的'concatBytes'函數,但是它能以更好的方式完成嗎? – codneto

+0

@codneto你的多字節如何存儲?例如如果你使用整數,你怎麼知道'0x3D7F'和'0x00003D7F'之間的區別?是的,我同意應該有一些本地'concat',但我不認爲應該有一個本地'push'或_length_改變 - 這不是類型化數組如何工作 –

+0

S,我有一些函數返回4個字節值,我需要添加到緩衝區。我也從流中讀取一些字節並追加到緩衝區,有時候基於某些標誌我必須讀取1,2或4個字節值,所有這些都需要附加到緩衝區。我應該如何完成將這些多字節值附加到緩衝區? – codneto

1

Paul的答案允許您將一個TypedArray連接到現有的TypedArray。在ES6,你可以用下面的函數來連接多個TypedArrays:

function concatenate(resultConstructor, ...arrays) { 
    let totalLength = 0; 
    for (const arr of arrays) { 
     totalLength += arr.length; 
    } 
    const result = new resultConstructor(totalLength); 
    let offset = 0; 
    for (const arr of arrays) { 
     result.set(arr, offset); 
     offset += arr.length; 
    } 
    return result; 
} 

const ta = concatenate(Uint8Array, 
    Uint8Array.of(1, 2), Uint8Array.of(3, 4)); 
console.log(ta); // Uint8Array [1, 2, 3, 4] 
console.log(ta.buffer.byteLength); // 4 

附加新的字節是:

const byte = 3; 
concatenate(Uint8Array, Uint8Array.of(1, 2), Uint8Array.of(byte)); 

這種方法在ExploringJS找到。