रॉ डेटा को ट्रांसफ़र करने के लिए, ArrayBuffers का इस्तेमाल किया जाता है. कई नए एपीआई इन पर निर्भर करते हैं. इनमें WebSockets, Web Intents 2](https://www.html5rocks.com/en/tutorials/file/xhr2/) और WebWorkers शामिल हैं. हालांकि, ये फ़ंक्शन हाल ही में JavaScript की दुनिया में आए हैं. इसलिए, कभी-कभी इनका गलत मतलब निकाला जाता है या इनका गलत इस्तेमाल किया जाता है.
सेमेटिक तौर पर, ArrayBuffer एक खास मास्क के ज़रिए देखे गए बाइट का ऐरे होता है.
यह मास्क, ArrayBufferView का एक इंस्टेंस है. इससे यह तय होता है कि कॉन्टेंट के अनुमानित स्ट्रक्चर से मैच करने के लिए, बाइट को कैसे अलाइन किया जाए. उदाहरण के लिए, अगर आपको पता है कि किसी ArrayBuffer में मौजूद बाइट, 16-बिट के बिना साइन वाले पूर्णांकों की कैटगरी के एरे को दिखाते हैं, तो ArrayBuffer को Uint16Array
व्यू में रैप करें. इसके बाद, ब्रैकेट सिंटैक्स का इस्तेमाल करके, उसके एलिमेंट में बदलाव किया जा सकता है. ऐसा करना वैसा ही है जैसे Uint16Array
एक पूर्णांक कैटगरी का एरे हो:
// 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 के बारे में एक आम सवाल यह है कि String
को ArrayBuffer
में और ArrayBuffer
को String
में कैसे बदलें. असल में, ArrayBuffer एक बाइट कलेक्शन होता है. इसलिए, इस कन्वर्ज़न के लिए ज़रूरी है कि दोनों पक्ष, स्ट्रिंग में वर्णों को बाइट के तौर पर दिखाने के तरीके पर सहमत हों. शायद आपने यह "समझौता" पहले भी देखा हो: यह स्ट्रिंग का वर्ण कोड है. उदाहरण के लिए, सामान्य "समझौते की शर्तें", यूनिकोड UTF-16 और iso8859-1 हैं. इसलिए, मान लें कि आपने और दूसरे पक्ष ने UTF-16 एन्कोडिंग पर सहमति जताई है, तो कन्वर्ज़न कोड कुछ ऐसा हो सकता है:
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
के इस्तेमाल पर ध्यान दें. यह एक ArrayBuffer व्यू है, जो ArrayBuffers के बाइट को 16-बिट एलिमेंट के तौर पर अलाइन करता है. यह कैरेक्टर एन्कोडिंग को खुद मैनेज नहीं करता. इसे String.fromCharCode
और
str.charCodeAt
, यूनिकोड के तौर पर मैनेज करते हैं.
StackOverflow पर इस बारे में पूछे गए एक लोकप्रिय सवाल के जवाब को सबसे ज़्यादा वोट मिले हैं. इसमें, स्ट्रिंग को फ़ॉर्मैट में बदलने का तरीका बताया गया है, जो थोड़ा मुश्किल है: FileReader
बनाएं, ताकि वह स्ट्रिंग को फ़ॉर्मैट में बदल सके. इसके बाद, उसमें Blob
फ़ीड करें. हालांकि, यह तरीका काम करता है, लेकिन इसे पढ़ना मुश्किल है और मुझे लगता है कि यह धीमा है. बिना वजह की आशंकाओं की वजह से, मानवता के इतिहास में कई गलतियां हुई हैं. इसलिए, यहां हम ज़्यादा वैज्ञानिक तरीके से बात करते हैं. मैंने दोनों तरीकों को jsperf की मदद से टेस्ट किया है और नतीजे से मेरी आशंका की पुष्टि हुई है. डेमो यहां देखें.
Chrome 20 में, इस लेख पर सीधे ArrayBuffer
मैनिपुलेशन कोड का इस्तेमाल करने से, FileReader
/Blob
तरीके का इस्तेमाल करने के मुकाबले, डेटा को 27 गुना ज़्यादा तेज़ी से मैनिपुलेट किया जा सकता है.