TypeScript में ArrayBuffer

यह लेख TypeScript में ArrayBuffer की व्याख्या करता है।

हम TypeScript में ArrayBuffer को स्टेप-बाय-स्टेप समझाएंगे, जिसमें मूल बातें और व्यावहारिक तकनीकों को शामिल करेंगे।

YouTube Video

TypeScript में ArrayBuffer

ArrayBuffer एक बिल्ट-इन ऑब्जेक्ट है जो बाइनरी डेटा के लिए 'कच्चे मेमोरी क्षेत्र' का प्रतिनिधित्व करता है। यह निश्चित लंबाई वाले कच्चे बफर का प्रतिनिधित्व करता है, जिस पर पढ़ने और लिखने के लिए TypedArray या DataView का उपयोग किया जाता है।

ArrayBuffer की मूल अवधारणाएं और विशेषताएँ

ArrayBuffer एक निश्चित-लंबाई वाली बाइट अनुक्रम (सीक्वेंस) है। इसे बनाते समय आप इसकी साइज बाइट्स में निर्दिष्ट करते हैं, और बाद में इसकी लंबाई बदली नहीं जा सकती।

1// Create a new ArrayBuffer of 16 bytes.
2const buf = new ArrayBuffer(16);
3console.log(buf.byteLength); // 16
  • यह कोड 16 बाइट्स का खाली बफर बनाता है। आप byteLength का उपयोग करके साइज देख सकते हैं।

टाइप्डएरे और डेटा-व्यू — बफर्स को संसाधित करने के लिए दृश्य

ArrayBuffer में डेटा पढ़ने या लिखने की क्षमता नहीं होती है। इसलिए, वास्तविक संचालन TypedArray या DataView के माध्यम से किए जाते हैं, जहाँ डेटा तक पहुँचते समय आप प्रकार जैसे पूर्णांक या फ्लोटिंग-पॉइंट नंबर और एंडियननेस निर्दिष्ट करते हैं।

1// Create a buffer and a Uint8Array view over it. Then write bytes and read them.
2const buffer = new ArrayBuffer(8);
3const u8 = new Uint8Array(buffer);
4
5u8[0] = 0x41; // 'A'
6u8[1] = 0x42; // 'B'
7console.log(u8); // Uint8Array(8) [ 65, 66, 0, 0, 0, 0, 0, 0 ]
  • Uint8Array बाइट-वार एरे दृश्य है, और इसे सामान्य ऐरे की तरह ऐक्सेस किया जा सकता है। यदि आप एक ही ArrayBuffer पर कई दृश्यों (व्यू) रखते हैं, तो वे पढ़ने और लिखने के लिए एक ही मेमोरी साझा करते हैं।

DataView: मनचाही सीमा और एंडियननेस पर पढ़ना और लिखना

DataView बाइट-स्तर पर बारीक पढ़ने और लिखने के लिए उपयोगी है, और आप इसमें लिटिल या बिग एंडियन निर्दिष्ट कर सकते हैं।

 1// Using DataView to write/read multi-byte values with endianness control.
 2const buf2 = new ArrayBuffer(8);
 3const view = new DataView(buf2);
 4
 5// Write a 32-bit integer (little-endian)
 6view.setInt32(0, 0x12345678, true);
 7
 8// Read it back as little-endian and big-endian
 9const little = view.getInt32(0, true);
10const big = view.getInt32(0, false);
11console.log(little.toString(16)); // "12345678"
12console.log(big.toString(16));    // "78563412"
  • DataView आपको मेमोरी में ऑफ़सेट निर्दिष्ट करके मान पढ़ने और लिखने की अनुमति देता है, जिससे यह उन प्रोटोकॉल के कार्यान्वयन के लिए उपयुक्त हो जाता है जिनमें नेटवर्क बाइट क्रम का प्रबंधन करना आवश्यक है।

Strings और ArrayBuffer के बीच रूपांतरण (TextEncoder / TextDecoder)

पाठ को बाइनरी में और बाइनरी को पाठ में बदलने के लिए TextEncoder और TextDecoder का उपयोग करें।

 1// Convert string -> ArrayBuffer and back using TextEncoder/TextDecoder.
 2const encoder = new TextEncoder();
 3const decoder = new TextDecoder();
 4
 5// Unicode escape sequences
 6const str = "\u3053\u3093\u306B\u3061\u306F";
 7const encoded = encoder.encode(str); // Uint8Array
 8console.log(encoded); // Uint8Array([...])
 9
10// If you need an ArrayBuffer specifically:
11const ab = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
12console.log(ab.byteLength); // bytes length of encoded text
13
14// Decode back
15const decoded = decoder.decode(encoded);
16console.log(decoded);
  • TextEncoder.encode एक Uint8Array लौटाता है, इसलिए यदि आपको ArrayBuffer की आवश्यकता है तो इसकी .buffer विशेषता का उपयोग करें। slice विधि के साथ, आप ऑफ़सेट और लंबाई निर्दिष्ट कर आवश्यक डेटा निकाल सकते हैं।

ArrayBuffer को स्लाइस करना और कॉपी करना

slice विधि एक नया ArrayBuffer लौटाती है। ArrayBuffer का आकार बदला नहीं जा सकता; अगर आवश्यकता हो तो एक नया बफर बनाएं और उसमें डेटा कॉपी करें।

 1// Slice an ArrayBuffer and copy to a new sized buffer.
 2const original = new Uint8Array([1,2,3,4,5]).buffer;
 3const part = original.slice(1, 4); // bytes 1..3
 4console.log(new Uint8Array(part)); // Uint8Array [ 2, 3, 4 ]
 5
 6// Resize: create a new buffer and copy existing content
 7const larger = new ArrayBuffer(10);
 8const target = new Uint8Array(larger);
 9target.set(new Uint8Array(original), 0);
10console.log(target); // first bytes filled with original data
  • चूंकि slice विधि एक नया ArrayBuffer लौटाती है, इसलिए यदि आप दक्षता या संदर्भ साझा करने को प्राथमिकता देते हैं, तो आप उसी बफर को संदर्भित करने के लिए TypedArray की subarray विधि का उपयोग कर सकते हैं।

TypedArray.subarray और कॉपी करने में अंतर

TypedArray का subarray एक नया व्यू लौटाता है, जो उसी ArrayBuffer को संदर्भित करता है।

1// subarray shares the same underlying buffer; modifying one affects the other.
2const arr = new Uint8Array([10,20,30,40]);
3const viewSub = arr.subarray(1,3); // shares memory
4viewSub[0] = 99;
5console.log(arr); // Uint8Array [10, 99, 30, 40]
  • साझा दृश्य कॉपी की लागत से बच सकते हैं, लेकिन चूंकि वे एक ही बफर को संदर्भित करते हैं, आपको साइड इफेक्ट्स के प्रति सतर्क रहना चाहिए।

बफर्स को जोड़ना (कई ArrayBuffer को एक साथ मिलाना)

ArrayBuffer निश्चित लंबाई का होता है, इसलिए कई बफर्स को जोड़ने के लिए नया ArrayBuffer बनाएं और डेटा कॉपी करें।

 1// Concatenate multiple ArrayBuffers
 2function concatBuffers(buffers: ArrayBuffer[]): ArrayBuffer {
 3  const total = buffers.reduce((sum, b) => sum + b.byteLength, 0);
 4  const result = new Uint8Array(total);
 5  let offset = 0;
 6  for (const b of buffers) {
 7    const u8 = new Uint8Array(b);
 8    result.set(u8, offset);
 9    offset += u8.length;
10  }
11  return result.buffer;
12}
13
14const a = new Uint8Array([1,2]).buffer;
15const b = new Uint8Array([3,4,5]).buffer;
16const c = concatBuffers([a, b]);
17console.log(new Uint8Array(c)); // [1,2,3,4,5]
  • यदि आप बार-बार बड़ी मात्रा में डेटा को जोड़ते हैं, तो कुल आकार की पूर्व-गणना करना और केवल एक बार नया बफर आवंटित करना, जैसा कि इस कोड में, अधिक कुशल है।

Worker में ArrayBuffer पास करना (Transferable)

ब्राउज़र के postMessage में, आप एक ArrayBuffer को "transferable" वस्तु के रूप में ट्रांसफर कर सकते हैं। मालिकाना हक बिना कॉपी किए स्थानांतरित किया जा सकता है, जिससे कॉपी की लागत से बचा जा सकता है।

1// Example: posting an ArrayBuffer to a Worker as a transferable object (browser)
2const worker = new Worker('worker.js');
3const bufferToSend = new Uint8Array([1,2,3,4]).buffer;
4
5// Transfer ownership to the worker (main thread no longer owns it)
6worker.postMessage(bufferToSend, [bufferToSend]);
7
8// After transfer, bufferToSend.byteLength === 0 in many browsers (detached)
9console.log(bufferToSend.byteLength); // may be 0
  • postMessage के दूसरे तर्क के रूप में ट्रांसफर की जाने वाली वस्तुओं की एक ऐरे निर्दिष्ट करके, आप ArrayBuffer जैसी ट्रांसफरेबल वस्तुओं का मालिकाना हक बिना कॉपी किए ट्रांसफर कर सकते हैं।
  • स्थानांतरण के बाद, बफर मूल पक्ष पर "detached" हो जाता है और उस तक पहुँचना संभव नहीं होता। SharedArrayBuffer का उपयोग करने से कई थ्रेड्स से एक साथ एक्सेस संभव होता है, लेकिन इसका उपयोग सुरक्षा आवश्यकताओं और पर्यावरणीय प्रतिबंधों के साथ आता है।

Node.js में हैंडलिंग (Buffer के साथ इंटरकन्वर्जन)

Node.js में, आप Node.js बाइनरी प्रकार Buffer और ArrayBuffer के बीच बदल सकते हैं। यह तब उपयोगी है जब आप TypeScript से दोनों—ब्राउज़र और Node.js—को लक्षित कर रहे हों।

 1// Convert ArrayBuffer <-> Node.js Buffer
 2// In Node.js environment:
 3const ab = new Uint8Array([10,20,30]).buffer;
 4const nodeBuffer = Buffer.from(ab); // ArrayBuffer -> Buffer
 5console.log(nodeBuffer); // <Buffer 0a 14 1e>
 6
 7const backToAb = nodeBuffer.buffer.slice(
 8    nodeBuffer.byteOffset,
 9    nodeBuffer.byteOffset + nodeBuffer.byteLength
10);
11console.log(new Uint8Array(backToAb)); // Uint8Array [10,20,30]
  • Node.js में Buffer.from(arrayBuffer) आमतौर पर कॉपी बनाता है, लेकिन कुछ मामलों में संदर्भ साझा संभव होता है, इसलिए ऑफ़सेट्स का ध्यान रखें।

प्रदर्शन विचार और सर्वोत्तम प्रथाएँ

प्रदर्शन अनुकूलित करने और ArrayBuffer को प्रभावी रूप से संभालने के लिए कुछ महत्वपूर्ण बिंदुओं को ध्यान में रखना चाहिए। नीचे, हम व्यावहारिक सर्वोत्तम प्रथाओं को सूचीबद्ध और समझाते हैं।

  • कॉपी की संख्या कम करें बड़े बाइनरी डेटा के साथ काम करते समय, कॉपी घटाने के लिए subarray (साझा व्यू) या ट्रांस्फरेबल्स का प्रयोग करें।

  • बड़े बफर्स एक बार में आवंटित करें बार-बार छोटे बफर आवंटित करने से ओवरहेड बढ़ जाता है। अगर संभव हो, तो एक बार में बड़ा बफर आवंटित करें और आवश्यकता अनुसार उसके हिस्सों का उपयोग करें।

  • एंडियननेस को स्पष्ट रूप से निर्दिष्ट करें मल्टीबाइट वैल्यूज के साथ काम करते समय, DataView का इस्तेमाल करें और एंडियननेस स्पष्ट रूप से निर्दिष्ट करें। नेटवर्क प्रोटोकॉल के लिए अक्सर बिग-एंडियन मानक होता है।

आम उपयोग के उदाहरण

ArrayBuffer का उपयोग ब्राउज़रों और Node.js दोनों में बड़े पैमाने पर होता है।

  1. बाइनरी प्रोटोकॉल को पार्स और बनाना (DataView के साथ हेडर जानकारी संसाधित करना)
  2. मीडिया प्रोसेसिंग जैसे इमेज और ऑडियो डेटा (fetch(...).then(res => res.arrayBuffer()))
  3. WebAssembly के लिए साझा मेमोरी (Wasm मेमोरी ArrayBuffer पर आधारित है)
  4. भारी प्रोसेसिंग को वर्कर में ऑफलोड करना (ArrayBuffer को transferable के रूप में पास करना)

निम्नलिखित कोड बाइनरी डेटा प्राप्त और विश्लेषण करने का उदाहरण है।

1// Example: fetch binary data in browser and inspect first bytes
2async function fetchAndInspect(url: string) {
3  const resp = await fetch(url);
4  const ab = await resp.arrayBuffer();
5  const u8 = new Uint8Array(ab, 0, Math.min(16, ab.byteLength));
6  console.log('first bytes:', u8);
7}
  • यह कोड ब्राउज़र में किसी भी URL से बाइनरी डेटा लाता है और शुरुआती कुछ बाइट्स दिखाता है। कोड fetch API के ज़रिए प्राप्त डेटा को ArrayBuffer के रूप में लोड करता है, और पहले 16 बाइट्स को Uint8Array से जांचता है।

सारांश

ArrayBuffer कच्चे मेमोरी का प्रतिनिधित्व करता है, जिससे TypedArray और DataView के माध्यम से कुशल बाइनरी ऑपरेशन संभव होते हैं। अनावश्यक कॉपी से बचाव और एंडियननेस को स्पष्ट रूप से निर्दिष्ट करने वाले डिज़ाइन से आप सुरक्षित व उच्च-प्रदर्शन बाइनरी प्रोसेसिंग प्राप्त कर सकते हैं।

आप हमारे YouTube चैनल पर Visual Studio Code का उपयोग करके ऊपर दिए गए लेख के साथ आगे बढ़ सकते हैं। कृपया YouTube चैनल को भी देखें।

YouTube Video