あらまし
ArrayBufferに格納された比較的サイズの大きいデータ(バイナリファイルなど)をリモートへ送信や受信したり、ウェブワーカーに渡す際に、UIのブロックを防ぐために小さな単位に分割したい場合がある。ここではArrayBufferを指定のサイズのセグメントに分割する方法と、複数のArrayBufferを単一のArrayBufferに結合する方法を紹介する。
分割
分割はArrayBufferのslice関数で行う。slice関数は、指定の開始から終了位置までのデータを保持した新しいArrayBufferオブジェクトを返す関数である。sliceされたデータは、もとのArrayBufferとは共有されず、新たにコピーされる。
function segmentation(arrayBuffer, segmentSize)
{
var segments= [];
var fi = 0;
while(fi*segmentSize< arrayBuffer.byteLength){
segments.push( arrayBuffer.slice(fi*segmentSize, (fi+1)*segmentSize) );
++fi;
}
return segments;
}
実行例
サイズ100のArrayBufferをサイズ30のセグメントに分割。30, 30, 30, 10のサイズの4つのArrayBufferに分割される。
結合
一旦Uint8Arrayで結合後のサイズ分の領域確保してから、set関数を使って各セグメントを該当位置に格納していゆく。
function concatenation(segments)
{
var sumLength = 0;
for(var i = 0; i < segments.length; ++i){
sumLength += segments[i].byteLength;
}
var whole = new Uint8Array(sumLength);
var pos = 0;
for(var i = 0; i < segments.length; ++i){
whole.set(new Uint8Array(segments[i]),pos);
pos += segments[i].byteLength;
}
return whole.buffer;
}
実行例
サイズ100のArrayBufferをサイズ30のセグメントに分割し、さらにそれらを結合して元に戻す。