টাইপস্ক্রিপ্টে অ্যারে-আপফার (ArrayBuffer)

টাইপস্ক্রিপ্টে অ্যারে-আপফার (ArrayBuffer)

এই প্রবন্ধে টাইপস্ক্রিপ্টে অ্যারে-আপফার ব্যাখ্যা করা হয়েছে।

আমরা টাইপস্ক্রিপ্টে অ্যারে-আপফার ধাপে ধাপে ব্যাখ্যা করবো, মৌলিক বিষয় থেকে শুরু করে ব্যবহারিক কৌশল পর্যন্ত।

YouTube Video

টাইপস্ক্রিপ্টে অ্যারে-আপফার (ArrayBuffer)

ArrayBuffer হলো একটি বিল্ট-ইন অবজেক্ট যা বাইনারি ডেটার “কাঁচা মেমোরি এলাকা” নির্দেশ করে। এটি একটি নির্দিষ্ট দৈর্ঘ্যের কাঁচা বাফার উপস্থাপন করে, যার উপর টাইপড অ্যারে (TypedArray) বা ডেটাভিউ (DataView) ব্যবহার করে পড়া ও লেখা যায়।

ArrayBuffer-এর মৌলিক ধারণা ও বৈশিষ্ট্যসমূহ

ArrayBuffer হলো নির্দিষ্ট দৈর্ঘ্যের বাইট সিরিজ। আপনি তৈরি করার সময় বাইটে আকার নির্ধারণ করেন এবং পরে এর দৈর্ঘ্য পরিবর্তন করা যায় না।

1// Create a new ArrayBuffer of 16 bytes.
2const buf = new ArrayBuffer(16);
3console.log(buf.byteLength); // 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 বাইট-ভিত্তিক সূক্ষ্মভাবে পড়া ও লেখার জন্য উপযোগী এবং এতে আপনি লিটল অথবা বিগ এন্ডিয়ান নির্ধারণ করতে পারেন।

 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 আপনাকে মেমোরিতে অফসেট নির্ধারণ করে ভ্যালু পড়া ও লেখা সম্ভব করে তোলে, যা নেটওয়ার্ক বাইট অর্ডার হ্যান্ডল করার মতো প্রোটোকল ইমপ্লিমেন্টেশনের জন্য উপযোগী।

স্ট্রিং ও ArrayBuffer-এর মধ্যে রূপান্তর (TextEncoder / TextDecoder)

টেক্সটকে বাইনারিতে এবং তার বিপরীতে রূপান্তর করতে TextEncoderTextDecoder ব্যবহার করুন।

 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]
  • আপনি যদি প্রায়ই বড় পরিমাণ ডেটা একত্রিত করেন, তবে পুরো সাইজ প্রাক-গণনা করে নতুন বাফার একবারই বরাদ্দ করা, যেমন এই কোডে দেখানো হয়েছে, আরও দক্ষ।

ওয়ার্কারে ArrayBuffer পাঠানো (ট্রান্সফারেবল)

ব্রাউজারের 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 ব্যবহারে একাধিক থ্রেড থেকে একসাথে অ্যাক্সেস করা যায়, তবে এর জন্য বিশেষ নিরাপত্তা শর্ত ও পরিবেশগত সীমাবদ্ধতা থাকে।

নোড.জেএস-এ ব্যবস্থাপনা (Buffer-এর সাথে আন্তরূপান্তর)

নোড.জেএস-এ, Node.js-এর বাইনারি টাইপ BufferArrayBuffer-এর মধ্যে রূপান্তর সম্ভব। টাইপস্ক্রিপ্ট দিয়ে ব্রাউজার ও নোড.জেএস দুইটি লক্ষ্যে কাজ করলেই এটি উপযোগী।

 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]
  • নোড.জেএস-এ Buffer.from(arrayBuffer) সাধারণত একটি কপি তৈরি করে, তবে ক্ষেত্র বিশেষে রেফারেন্সও ভাগাভাগি হতে পারে, তাই অফসেটের ব্যাপারে সতর্ক থাকুন।

কর্মদক্ষতা সংক্রান্ত বিষয় ও সেরা অভ্যাসসমূহ

পারফরম্যান্স বাড়াতে ও ArrayBuffer দক্ষভাবে ব্যবহার করতে কিছু গুরুত্বপূর্ণ বিষয় মনে রাখা দরকার। নিম্নে আমরা ব্যবহারিক সেরা অভ্যাস তালিকাভুক্ত ও ব্যাখ্যা করছি।

  • কপি করার সংখ্যা কমান বড় বাইনারি ডেটা ব্যবহারে, subarray (ভিউ ভাগাভাগি) বা transferable ব্যবহার করে কপি কমান।

  • একবারে বড় বাফার বরাদ্দ করুন ছোট বাফার বারবার বরাদ্দ করা অতিরিক্ত ওভারহেড বাড়িয়ে দেয়। সম্ভব হলে, একবারে একটি বড় বাফার বরাদ্দ করুন এবং প্রয়োজনে তার অংশ ব্যবহার করুন।

  • এন্ডিয়াননেস স্পষ্টভাবে নির্ধারণ করুন বহুবাইট মান ব্যবহারে DataView দিয়ে স্পষ্টভাবে এন্ডিয়াননেস নির্ধারণ করুন। নেটওয়ার্ক প্রোটোকলে বিগ-এন্ডিয়ান প্রায়ই স্ট্যান্ডার্ড হিসেবে ব্যবহৃত হয়।

সাধারণ ব্যবহারের উদাহরণসমূহ

ব্রাউজার ও নোড.জেএস উভয় ক্ষেত্রেই ArrayBuffer ব্যাপকভাবে ব্যবহৃত হয়।

  1. বাইনারি প্রোটোকল পার্স করা ও গঠন (হেডার তথ্য DataView-এর মাধ্যমে প্রক্রিয়াকরণ)
  2. মিডিয়া প্রসেসিং যেমন ছবি ও অডিও ডেটা (fetch(...).then(res => res.arrayBuffer()))
  3. WebAssembly-র জন্য শেয়ার্ড মেমোরি (Wasm মেমোরি ArrayBuffer-এর উপর ভিত্তি করে কাজ করে)
  4. ভারী প্রসেসিং ওয়ার্কার-এ হস্তান্তর (transferable হিসেবে ArrayBuffer প্রেরণ)

নিম্নের কোড বাইনারি ডেটা সংগ্রহ ও বিশ্লেষণের একটি উদাহরণ।

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}
  • এই কোডটি ব্রাউজারে যেকোনো ইউআরএল থেকে বাইনারি ডেটা নিয়ে প্রথম কয়েকটি বাইট দেখায়। কোডটি fetch API দিয়ে আনা ডেটা ArrayBuffer হিসেবে লোড করে এবং প্রথম ১৬ বাইট Uint8Array দিয়ে পরীক্ষা করে।

সারসংক্ষেপ

ArrayBuffer হলো কাঁচা মেমোরির উপস্থাপনা, যাতে TypedArray ও DataView ব্যবহার করে দক্ষ বাইনারি অপারেশন সম্ভব। অপ্রয়োজনীয় কপি এড়িয়ে এবং স্পষ্টভাবে এন্ডিয়াননেস নির্ধারণ করে ডিজাইন করলে, নিরাপদ ও উচ্চ-কর্মদক্ষতা বিশিষ্ট বাইনারি প্রক্রিয়াকরণ সম্ভব।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video