Ham verileri aktarmak için kullanılan ArrayBuffer'lar, WebSockets, Web Intents 2](https://www.html5rocks.com/en/tutorials/file/xhr2/) ve WebWorkers dahil olmak üzere çeşitli yeni API'ler tarafından kullanılır. Ancak bu işlevler JavaScript dünyasına kısa süre önce eklendiğinden bazen yanlış yorumlanır veya kötüye kullanılır.
Anlamsal olarak, ArrayBuffer yalnızca belirli bir maske aracılığıyla görüntülenen bir bayt dizisidir.
ArrayBufferView örneği olan bu maske, baytların içeriğin beklenen yapısıyla eşleşecek şekilde nasıl hizalandığını tanımlar. Örneğin, bir ArrayBuffer'daki baytların 16 bitlik işaretsiz tam sayı dizisini temsil ettiğini biliyorsanız ArrayBuffer'ı bir Uint16Array
görünümüne sarmalamak yeterlidir. Ardından, Uint16Array
bir tam sayı dizisiymiş gibi parantez söz dizimini kullanarak öğelerini değiştirebilirsiniz:
// suppose buf contains the bytes [0x02, 0x01, 0x03, 0x07]
// notice the multibyte values respect the hardware endianess, which is little-endian in x86
var bufView = new Uint16Array(buf);
if (bufView[0]===258) { // 258 === 0x0102
console.log("ok");
}
bufView[0] = 255; // buf now contains the bytes [0xFF, 0x00, 0x03, 0x07]
bufView[0] = 0xff05; // buf now contains the bytes [0x05, 0xFF, 0x03, 0x07]
bufView[1] = 0x0210; // buf now contains the bytes [0x05, 0xFF, 0x10, 0x02]
ArrayBuffer ile ilgili sık sorulan sorulardan biri, String
'ün ArrayBuffer
'e ve bunun tersi dönüşümü nasıl yapılacağıdır. ArrayBuffer aslında bir bayt dizisi olduğundan bu dönüşüm, her iki tarafın da dizesindeki karakterlerin bayt olarak nasıl temsil edileceği konusunda anlaşmasını gerektirir. Bu "sözleşmeyi" daha önce görmüş olabilirsiniz: Bu, dizenin karakter kodlamasıdır (ve normal "sözleşme şartları " örneğin Unicode UTF-16 ve iso8859-1'dir). Bu nedenle, sizinle diğer tarafın UTF-16 kodlamasını kabul ettiğini varsayarsak dönüşüm kodu şu şekilde olabilir:
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function str2ab(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
Uint16Array
değerinin kullanıldığını unutmayın. Bu, ArrayBuffer'ların baytlarını 16 bitlik öğeler olarak hizalayan bir ArrayBuffer görünümüdür. Karakter kodlamasını kendisi işlemez. Bu işlem String.fromCharCode
ve str.charCodeAt
tarafından Unicode olarak gerçekleştirilir.
Bu konuyla ilgili popüler bir StackOverflow sorusunda, dönüşüm için oldukça karmaşık bir çözüm içeren ve çok sayıda oy alan bir yanıt yer alır: Dönüştürücü olarak kullanılacak bir FileReader
oluşturun ve dize içeren bir Blob
besleyin. Bu yöntem işe yaramasına rağmen okunabilirliği düşüktür ve yavaş olduğu düşünülmektedir. Asılsız şüpheler, insanlık tarihinde birçok hataya yol açtığından bu konuyu daha bilimsel bir yaklaşımla ele alalım. İki yöntemi jsperf ile test ettim ve sonuç şüphelerimi doğruladı. Demoyu buradan inceleyebilirsiniz.
Chrome 20'de, bu makaledeki doğrudan ArrayBuffer
değiştirme kodunu kullanmak, FileReader
/Blob
yöntemini kullanmaktan neredeyse 27 kat daha hızlıdır.