Skip to content

تهدف هذه الصفحة إلى أن تكون مقدمة للعمل مع البيانات الثنائية في JavaScript. يطبق Bun عدداً من أنواع البيانات والأدوات المساعدة للتعامل مع البيانات الثنائية، ومعظمها معيار ويب. سيتم ملاحظة أي واجهات برمجة تطبيقات خاصة بـ Bun على هذا النحو.

فيما يلي "ورقة غش" سريعة تعمل أيضاً كفهرس للمحتويات. انقر على عنصر في العمود الأيمن للانتقال إلى ذلك القسم.

الفئةالوصف
TypedArrayعائلة من الفئات التي توفر واجهة شبيهة بـ Array للتفاعل مع البيانات الثنائية. تشمل Uint8Array وUint16Array وInt8Array والمزيد.
Bufferفئة فرعية من Uint8Array تطبق مجموعة واسعة من طرق الراحة. على عكس العناصر الأخرى في هذا الجدول، هذه هي واجهة برمجة تطبيقات Node.js (التي يطبقها Bun). لا يمكن استخدامها في المتصفح.
DataViewفئة توفر واجهة برمجة تطبيقات get/set لكتابة عدد من البايتات إلى ArrayBuffer عند إزاحة بايت معينة. تُستخدم غالباً لقراءة أو كتابة البروتوكولات الثنائية.
Blobكتلة ثنائية للقراءة فقط تمثل عادةً ملفاً. تحتوي على type MIME وsize وطرق للتحويل إلى ArrayBuffer وReadableStream وstring.
Fileفئة فرعية من Blob تمثل ملفاً. تحتوي على خاصيتي name وlastModified. هناك دعم تجريبي في Node.js v20.
BunFileBun فقط. فئة فرعية من Blob تمثل ملفاً يتم تحميله بشكل كسول على القرص. يتم إنشاؤها باستخدام Bun.file(path).

ArrayBuffer والعروض

حتى عام 2009، لم تكن هناك طريقة أصلية في اللغة لتخزين والتلاعب بالبيانات الثنائية في JavaScript. قدم ECMAScript v5 مجموعة من الآليات الجديدة لهذا الغرض. لبنة البناء الأساسية هي ArrayBuffer، وهي بنية بيانات بسيطة تمثل سلسلة من البايتات في الذاكرة.

ts
// هذا المخزن المؤقت يمكنه تخزين 8 بايتات
const buf = new ArrayBuffer(8);

على الرغم من الاسم، فهو ليس مصفوفة ولا يدعم أي من طرق ومشغلات المصفوفة التي قد يتوقعها المرء. في الواقع، لا توجد طريقة لقراءة أو كتابة القيم مباشرة من ArrayBuffer. هناك القليل جداً الذي يمكنك فعله به باستثناء التحقق من حجمه وإنشاء "شرائح" منه.

ts
const buf = new ArrayBuffer(8);
buf.byteLength; // => 8

const slice = buf.slice(0, 4); // يُرجع ArrayBuffer جديد
slice.byteLength; // => 4

لفعل أي شيء مثير للاهتمام، نحتاج إلى بناء معروف باسم "view" (عرض). العرض هو فئة تغلف مثيل ArrayBuffer وتسمح لك بقراءة والتلاعب بالبيانات الأساسية. هناك نوعان من العروض: typed arrays (المصفوفات المكتوبة) وDataView.

DataView

فئة DataView هي واجهة منخفضة المستوى لقراءة والتلاعب بالبيانات في ArrayBuffer.

فيما يلي ننشئ DataView جديد ونضبط البايت الأول على 3.

ts
const buf = new ArrayBuffer(4);
// [0b00000000, 0b00000000, 0b00000000, 0b00000000]

const dv = new DataView(buf);
dv.setUint8(0, 3); // كتابة القيمة 3 عند إزاحة البايت 0
dv.getUint8(0); // => 3
// [0b00000011, 0b00000000, 0b00000000, 0b00000000]

الآن دعنا نكتب Uint16 عند إزاحة البايت 1. هذا يتطلب بايتين. نحن نستخدم القيمة 513، وهي 2 * 256 + 1؛ بالبايتات، هذا 00000010 00000001.

ts
dv.setUint16(1, 513);
// [0b00000011, 0b00000010, 0b00000001, 0b00000000]

console.log(dv.getUint16(1)); // => 513

لقد قمنا الآن بتعيين قيمة للبايتات الثلاثة الأولى في ArrayBuffer الأساسي الخاص بنا. على الرغم من أن البايتات الثانية والثالثة تم إنشاؤها باستخدام setUint16()، لا يزال بإمكاننا قراءة كل بايت من مكوناتها باستخدام getUint8().

ts
console.log(dv.getUint8(1)); // => 2
console.log(dv.getUint8(2)); // => 1

محاولة كتابة قيمة تتطلب مساحة أكبر مما هو متاح في ArrayBuffer الأساسي ستسبب خطأ. فيما يلي نحاول كتابة Float64 (الذي يتطلب 8 بايتات) عند إزاحة البايت 0، ولكن هناك أربعة بايتات فقط في المجموع في المخزن المؤقت.

ts
dv.setFloat64(0, 3.1415);
// ^ RangeError: Out of bounds access

الطرق التالية متاحة على DataView:

GettersSetters
getBigInt64()setBigInt64()
getBigUint64()setBigUint64()
getFloat32()setFloat32()
getFloat64()setFloat64()
getInt16()setInt16()
getInt32()setInt32()
getInt8()setInt8()
getUint16()setUint16()
getUint32()setUint32()
getUint8()setUint8()

TypedArray

المصفوفات المكتوبة هي عائلة من الفئات التي توفر واجهة شبيهة بـ Array للتفاعل مع البيانات في ArrayBuffer. بينما يسمح لك DataView بكتابة أرقام بأحجام مختلفة عند إزاحة معينة، تفسر TypedArray البايتات الأساسية كمصفوفة من الأرقام، كل منها بحجم ثابت.

NOTE

من الشائع الإشارة إلى عائلة الفئات هذه بشكل جماعي بواسطة الفئة الفائقة المشتركة `TypedArray`. هذه الفئة _داخلية_ لـ JavaScript؛ لا يمكنك إنشاء مثيلات منها مباشرة، و`TypedArray` غير معرفة في النطاق العام. فكر فيها كـ `interface` أو فئة مجردة.
ts
const buffer = new ArrayBuffer(3);
const arr = new Uint8Array(buffer);

// يتم تهيئة المحتويات إلى الصفر
console.log(arr); // Uint8Array(3) [0, 0, 0]

// تعيين القيم مثل المصفوفة
arr[0] = 0;
arr[1] = 10;
arr[2] = 255;
arr[3] = 255; // لا تأثير، خارج الحدود

بينما ArrayBuffer هو تسلسل عام من البايتات، تفسر فئات المصفوفات المكتوبة هذه البايتات كمصفوفة من الأرقام بحجم بايت معين. الصف العلوي يحتوي على البايتات الخام، والصفوف اللاحقة تحتوي على كيفية تفسير هذه البايتات عند عرضها باستخدام فئات مصفوفات مكتوبة مختلفة.

الفئات التالية هي مصفوفات مكتوبة، مع وصف لكيفية تفسيرها للبايتات في ArrayBuffer:

الفئةالوصف
Uint8Arrayكل بايت واحد (1) يُفسر كعدد صحيح غير موقع 8-بت. النطاق من 0 إلى 255.
Uint16Arrayكل بايتين (2) تُفسر كعدد صحيح غير موقع 16-بت. النطاق من 0 إلى 65535.
Uint32Arrayكل أربع بايتات (4) تُفسر كعدد صحيح غير موقع 32-بت. النطاق من 0 إلى 4294967295.
Int8Arrayكل بايت واحد (1) يُفسر كعدد صحيح موقع 8-بت. النطاق من -128 إلى 127.
Int16Arrayكل بايتين (2) تُفسر كعدد صحيح موقع 16-بت. النطاق من -32768 إلى 32767.
Int32Arrayكل أربع بايتات (4) تُفسر كعدد صحيح موقع 32-بت. النطاق من -2147483648 إلى 2147483647.
Float16Arrayكل بايتين (2) تُفسر كعدد فاصلة عائمة 16-بت. النطاق من -6.104e5 إلى 6.55e4.
Float32Arrayكل أربع بايتات (4) تُفسر كعدد فاصلة عائمة 32-بت. النطاق من -3.4e38 إلى 3.4e38.
Float64Arrayكل ثمان بايتات (8) تُفسر كعدد فاصلة عائمة 64-بت. النطاق من -1.7e308 إلى 1.7e308.
BigInt64Arrayكل ثمان بايتات (8) تُفسر كـ BigInt موقع. النطاق من -9223372036854775808 إلى 9223372036854775807 (على الرغم من أن BigInt قادر على تمثيل أرقام أكبر).
BigUint64Arrayكل ثمان بايتات (8) تُفسر كـ BigInt غير موقع. النطاق من 0 إلى 18446744073709551615 (على الرغم من أن BigInt قادر على تمثيل أرقام أكبر).
Uint8ClampedArrayنفس Uint8Array، ولكن "تثبت" تلقائياً إلى النطاق 0-255 عند تعيين قيمة لعنصر.

الجدول أدناه يوضح كيفية تفسير البايتات في ArrayBuffer عند عرضها باستخدام فئات مصفوفات مكتوبة مختلفة.

Byte 0Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6Byte 7
ArrayBuffer0000000000000001000000100000001100000100000001010000011000000111
Uint8Array01234567
Uint16Array256 (1 * 256 + 0)770 (3 * 256 + 2)1284 (5 * 256 + 4)1798 (7 * 256 + 6)
Uint32Array50462976117835012
BigUint64Array506097522914230528n

لإنشاء مصفوفة مكتوبة من ArrayBuffer محدد مسبقاً:

ts
// إنشاء مصفوفة مكتوبة من ArrayBuffer
const buf = new ArrayBuffer(10);
const arr = new Uint8Array(buf);

arr[0] = 30;
arr[1] = 60;

// جميع العناصر مهيئة إلى الصفر
console.log(arr); // => Uint8Array(10) [ 30, 60, 0, 0, 0, 0, 0, 0, 0, 0 ];

إذا حاولنا إنشاء مثيل Uint32Array من نفس ArrayBuffer، سنحصل على خطأ.

ts
const buf = new ArrayBuffer(10);
const arr = new Uint32Array(buf);
//          ^  RangeError: ArrayBuffer length minus the byteOffset
//             is not a multiple of the element size

قيمة Uint32 تتطلب أربع بايتات (16 بت). لأن ArrayBuffer طوله 10 بايتات، لا توجد طريقة لتقسيم محتوياته بشكل نظيف إلى قطع من 4 بايتات.

لإصلاح هذا، يمكننا إنشاء مصفوفة مكتوبة فوق "شريحة" معينة من ArrayBuffer. Uint16Array أدناه "تعرض" فقط أول 8 بايتات من ArrayBuffer الأساسي. لتحقيق ذلك، نحدد byteOffset بمقدار 0 وlength بمقدار 2، مما يشير إلى عدد أرقام Uint32 التي نريد أن تحتويها مصفوفتنا.

ts
// إنشاء مصفوفة مكتوبة من شريحة ArrayBuffer
const buf = new ArrayBuffer(10);
const arr = new Uint32Array(buf, 0, 2);

/*
  buf    _ _ _ _ _ _ _ _ _ _    10 bytes
  arr   [_______,_______]       2 عناصر 4-بايت
*/

arr.byteOffset; // 0
arr.length; // 2

لا تحتاج إلى إنشاء مثيل ArrayBuffer صراحة؛ يمكنك بدلاً من ذلك تحديد طول مباشرة في منشئ المصفوفة المكتوبة:

ts
const arr2 = new Uint8Array(5);

// جميع العناصر مهيئة إلى الصفر
// => Uint8Array(5) [0, 0, 0, 0, 0]

يمكن أيضاً إنشاء مثيلات المصفوفات المكتوبة مباشرة من مصفوفة من الأرقام، أو من مصفوفة مكتوبة أخرى:

ts
// من مصفوفة من الأرقام
const arr1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);
arr1[0]; // => 0;
arr1[7]; // => 7;

// من مصفوفة مكتوبة أخرى
const arr2 = new Uint8Array(arr);

بشكل عام، توفر المصفوفات المكتوبة نفس الطرق مثل المصفوفات العادية، مع بعض الاستثناءات. على سبيل المثال، push وpop غير متاحتين على المصفوفات المكتوبة، لأنها ستتطلب تغيير حجم ArrayBuffer الأساسي.

ts
const arr = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]);

// تدعم طرق المصفوفة الشائعة
arr.filter(n => n > 128); // Uint8Array(1) [255]
arr.map(n => n * 2); // Uint8Array(8) [0, 2, 4, 6, 8, 10, 12, 14]
arr.reduce((acc, n) => acc + n, 0); // 28
arr.forEach(n => console.log(n)); // 0 1 2 3 4 5 6 7
arr.every(n => n < 10); // true
arr.find(n => n > 5); // 6
arr.includes(5); // true
arr.indexOf(5); // 5

راجع توثيق MDN للحصول على مزيد من المعلومات حول خصائص وطرق المصفوفات المكتوبة.

Uint8Array

من الجدير تسليط الضوء بشكل خاص على Uint8Array، لأنها تمثل "مصفوفة بايتات" كلاسيكية—سلسلة من الأعداد الصحيحة غير الموقعة 8-بت بين 0 و 255. هذه هي المصفوفة المكتوبة الأكثر شيوعاً التي ستواجهها في JavaScript.

في Bun، ويوماً ما في محركات JavaScript الأخرى، تتوفر طرق للتحويل بين مصفوفات البايتات والتمثيلات المتسلسلة لتلك المصفوفات كسلاسل base64 أو hex.

ts
new Uint8Array([1, 2, 3, 4, 5]).toBase64(); // "AQIDBA=="
Uint8Array.fromBase64("AQIDBA=="); // Uint8Array(4) [1, 2, 3, 4, 5]

new Uint8Array([255, 254, 253, 252, 251]).toHex(); // "fffefdfcfb=="
Uint8Array.fromHex("fffefdfcfb"); // Uint8Array(5) [255, 254, 253, 252, 251]

هي قيمة الإرجاع لـ TextEncoder#encode، ونوع الإدخال لـ TextDecoder#decode، فئتان مساعدتان مصممتان لترجمة السلاسل ومختلف الترميزات الثنائية، وأبرزها "utf-8".

ts
const encoder = new TextEncoder();
const bytes = encoder.encode("hello world");
// => Uint8Array(11) [ 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]

const decoder = new TextDecoder();
const text = decoder.decode(bytes);
// => hello world

Buffer

يطبق Bun Buffer، وهي واجهة برمجة تطبيقات Node.js للعمل مع البيانات الثنائية التي سبقت إدخال المصفوفات المكتوبة في مواصفات JavaScript. أعيد تنفيذها منذ ذلك الحين كفئة فرعية من Uint8Array. توفر مجموعة واسعة من الطرق، بما في ذلك عدة طرق شبيهة بالمصفوفة وDataView.

ts
const buf = Buffer.from("hello world");
// => Buffer(11) [ 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]

buf.length; // => 11
buf[0]; // => 104، ascii لـ 'h'
buf.writeUInt8(72, 0); // => ascii لـ 'H'

console.log(buf.toString());
// => Hello world

للحصول على التوثيق الكامل، راجع توثيق Node.js.

Blob

Blob هي واجهة برمجة تطبيقات ويب تُستخدم عادةً لتمثيل الملفات. تم تنفيذ Blob في البداية في المتصفحات (على عكس ArrayBuffer الذي هو جزء من JavaScript نفسها)، ولكنها مدعومة الآن في Node و Bun.

ليس من الشائع إنشاء مثيلات Blob مباشرة. في كثير من الأحيان، ستستلم مثيلات Blob من مصدر خارجي (مثل عنصر <input type="file"> في المتصفح) أو مكتبة. مع ذلك، من الممكن إنشاء Blob من جزء واحد أو أكثر من أجزاء "blob" الثنائية أو السلسلة.

ts
const blob = new Blob(["<html>Hello</html>"], {
  type: "text/html",
});

blob.type; // => text/html
blob.size; // => 19

يمكن أن تكون هذه الأجزاء string أو ArrayBuffer أو TypedArray أو DataView أو مثيلات Blob أخرى. يتم دمج أجزاء blob معاً بالترتيب الذي تم توفيرها به.

ts
const blob = new Blob([
  "<html>",
  new Blob(["<body>"]),
  new Uint8Array([104, 101, 108, 108, 111]), // "hello" بالثنائية
  "</body></html>",
]);

يمكن قراءة محتويات Blob بشكل غير متزامن بتنسيقات مختلفة.

ts
await blob.text(); // => <html><body>hello</body></html>
await blob.bytes(); // => Uint8Array (ينسخ المحتويات)
await blob.arrayBuffer(); // => ArrayBuffer (ينسخ المحتويات)
await blob.stream(); // => ReadableStream

BunFile

BunFile هي فئة فرعية من Blob تُستخدم لتمثيل ملف يتم تحميله بشكل كسول على القرص. مثل File، تضيف خاصيتي name وlastModified. على عكس File، لا تتطلب تحميل الملف إلى الذاكرة.

ts
const file = Bun.file("index.txt");
// => BunFile

File

File هي فئة فرعية من Blob تضيف خاصيتي name وlastModified. تُستخدم عادةً في المتصفح لتمثيل الملفات المرفوعة عبر عنصر <input type="file">. يطبق Node.js و Bun File.

ts
// على المتصفح!
// <input type="file" id="file" />

const files = document.getElementById("file").files;
// => File[]
ts
const file = new File(["<html>Hello</html>"], "index.html", {
  type: "text/html",
});

راجع توثيق MDN للحصول على معلومات التوثيق الكاملة.


Streams

التيارات هي تجريد مهم للعمل مع البيانات الثنائية دون تحميلها جميعاً في الذاكرة دفعة واحدة. تُستخدم عادةً لقراءة وكتابة الملفات، وإرسال واستقبال طلبات الشبكة، ومعالجة كميات كبيرة من البيانات.

يطبق Bun واجهات برمجة تطبيقات الويب ReadableStream وWritableStream.

NOTE

يطبق Bun أيضاً وحدة `node:stream`، بما في ذلك [`Readable`](https://nodejs.org/api/stream.html#stream_readable_streams)، [`Writable`](https://nodejs.org/api/stream.html#stream_writable_streams)، و [`Duplex`](https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams). للحصول على التوثيق الكامل، راجع توثيق Node.js.

لإنشاء تيار قابل للقراءة بسيط:

ts
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("hello");
    controller.enqueue("world");
    controller.close();
  },
});

يمكن قراءة محتويات هذا التيار قطعة تلو الأخرى باستخدام صيغة for await.

ts
for await (const chunk of stream) {
  console.log(chunk);
}

// => "hello"
// => "world"

لمناقشة أكثر اكتمالاً للتيارات في Bun، راجع API > Streams.


Conversion

التحويل من تنسيق ثنائي إلى آخر هو مهمة شائعة. يهدف هذا القسم إلى أن يكون مرجعاً.

من ArrayBuffer

بما أن ArrayBuffer يخزن البيانات التي تكمن وراء هياكل ثنائية أخرى مثل TypedArray، فإن المقاطع أدناه لا تحول من ArrayBuffer إلى تنسيق آخر. بدلاً من ذلك، هي تنشئ مثيلاً جديداً باستخدام البيانات المخزنة في البيانات الأساسية.

إلى TypedArray

ts
new Uint8Array(buf);

إلى DataView

ts
new DataView(buf);

إلى Buffer

ts
// إنشاء Buffer على كامل ArrayBuffer
Buffer.from(buf);

// إنشاء Buffer على شريحة من ArrayBuffer
Buffer.from(buf, 0, 10);

إلى string

كـ UTF-8:

ts
new TextDecoder().decode(buf);

إلى number[]

ts
Array.from(new Uint8Array(buf));

إلى Blob

ts
new Blob([buf], { type: "text/plain" });

إلى ReadableStream

المقطع التالي ينشئ ReadableStream ويضيف ArrayBuffer بالكامل كقطعة واحدة.

ts
new ReadableStream({
  start(controller) {
    controller.enqueue(buf);
    controller.close();
  },
});

مع التقطيع">

لبث ArrayBuffer في قطع، استخدم عرض Uint8Array وأضف كل قطعة.

ts
const view = new Uint8Array(buf);
const chunkSize = 1024;

new ReadableStream({
  start(controller) {
    for (let i = 0; i < view.length; i += chunkSize) {
      controller.enqueue(view.slice(i, i + chunkSize));
    }
    controller.close();
  },
});

من TypedArray

إلى ArrayBuffer

هذا يسترجع ArrayBuffer الأساسي. لاحظ أن TypedArray يمكن أن تكون عرضاً لـ شريحة من المخزن المؤقت الأساسي، لذا قد تختلف الأحجام.

ts
arr.buffer;

إلى DataView

لإنشاء DataView على نفس نطاق البايتات مثل TypedArray.

ts
new DataView(arr.buffer, arr.byteOffset, arr.byteLength);

إلى Buffer

ts
Buffer.from(arr);

إلى string

كـ UTF-8:

ts
new TextDecoder().decode(arr);

إلى number[]

ts
Array.from(arr);

إلى Blob

ts
// فقط إذا كان arr عرضاً لمصفوفة TypedArray الداعمة بالكامل
new Blob([arr.buffer], { type: "text/plain" });

إلى ReadableStream

ts
new ReadableStream({
  start(controller) {
    controller.enqueue(arr);
    controller.close();
  },
});

مع التقطيع">

لبث ArrayBuffer في قطع، قسّم TypedArray إلى قطع وأضف كل واحدة بشكل فردي.

ts
new ReadableStream({
  start(controller) {
    for (let i = 0; i < arr.length; i += chunkSize) {
      controller.enqueue(arr.slice(i, i + chunkSize));
    }
    controller.close();
  },
});

من DataView

إلى ArrayBuffer

ts
view.buffer;

إلى TypedArray

تعمل فقط إذا كان byteLength لـ DataView هو مضاعف لـ BYTES_PER_ELEMENT لفئة TypedArray الفرعية.

ts
new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
new Uint16Array(view.buffer, view.byteOffset, view.byteLength / 2);
new Uint32Array(view.buffer, view.byteOffset, view.byteLength / 4);
// إلخ...

إلى Buffer

ts
Buffer.from(view.buffer, view.byteOffset, view.byteLength);

إلى string

كـ UTF-8:

ts
new TextDecoder().decode(view);

إلى number[]

ts
Array.from(view);

إلى Blob

ts
new Blob([view.buffer], { type: "text/plain" });

إلى ReadableStream

ts
new ReadableStream({
  start(controller) {
    controller.enqueue(view.buffer);
    controller.close();
  },
});

مع التقطيع">

لبث ArrayBuffer في قطع، قسّم DataView إلى قطع وأضف كل واحدة بشكل فردي.

ts
new ReadableStream({
  start(controller) {
    for (let i = 0; i < view.byteLength; i += chunkSize) {
      controller.enqueue(view.buffer.slice(i, i + chunkSize));
    }
    controller.close();
  },
});

من Buffer

إلى ArrayBuffer

ts
buf.buffer;

إلى TypedArray

ts
new Uint8Array(buf);

إلى DataView

ts
new DataView(buf.buffer, buf.byteOffset, buf.byteLength);

إلى string

كـ UTF-8:

ts
buf.toString();

كـ base64:

ts
buf.toString("base64");

كـ hex:

ts
buf.toString("hex");

إلى number[]

ts
Array.from(buf);

إلى Blob

ts
new Blob([buf], { type: "text/plain" });

إلى ReadableStream

ts
new ReadableStream({
  start(controller) {
    controller.enqueue(buf);
    controller.close();
  },
});

مع التقطيع">

لبث ArrayBuffer في قطع، قسّم Buffer إلى قطع وأضف كل واحدة بشكل فردي.

ts
new ReadableStream({
  start(controller) {
    for (let i = 0; i < buf.length; i += chunkSize) {
      controller.enqueue(buf.slice(i, i + chunkSize));
    }
    controller.close();
  },
});

من Blob

إلى ArrayBuffer

توفر فئة Blob طريقة راحة لهذا الغرض.

ts
await blob.arrayBuffer();

إلى TypedArray

ts
await blob.bytes();

إلى DataView

ts
new DataView(await blob.arrayBuffer());

إلى Buffer

ts
Buffer.from(await blob.arrayBuffer());

إلى string

كـ UTF-8:

ts
await blob.text();

إلى number[]

ts
Array.from(await blob.bytes());

إلى ReadableStream

ts
blob.stream();

من ReadableStream

من الشائع استخدام Response كتمثيل وسيط مناسب لتسهيل تحويل ReadableStream إلى تنسيقات أخرى.

ts
stream; // ReadableStream

const buffer = new Response(stream).arrayBuffer();

مع ذلك هذا النهج مطول ويضيف نفقات عامة تبطئ الأداء العام بشكل غير ضروري. يطبق Bun مجموعة من دوال الراحة المحسنة لتحويل ReadableStream إلى تنسيقات ثنائية مختلفة.

إلى ArrayBuffer

ts
// مع Response
new Response(stream).arrayBuffer();

// مع دالة Bun
Bun.readableStreamToArrayBuffer(stream);

إلى Uint8Array

ts
// مع Response
new Response(stream).bytes();

// مع دالة Bun
Bun.readableStreamToBytes(stream);

إلى TypedArray

ts
// مع Response
const buf = await new Response(stream).arrayBuffer();
new Int8Array(buf);

// مع دالة Bun
new Int8Array(Bun.readableStreamToArrayBuffer(stream));

إلى DataView

ts
// مع Response
const buf = await new Response(stream).arrayBuffer();
new DataView(buf);

// مع دالة Bun
new DataView(Bun.readableStreamToArrayBuffer(stream));

إلى Buffer

ts
// مع Response
const buf = await new Response(stream).arrayBuffer();
Buffer.from(buf);

// مع دالة Bun
Buffer.from(Bun.readableStreamToArrayBuffer(stream));

إلى string

كـ UTF-8:

ts
// مع Response
await new Response(stream).text();

// مع دالة Bun
await Bun.readableStreamToText(stream);

إلى number[]

ts
// مع Response
const arr = await new Response(stream).bytes();
Array.from(arr);

// مع دالة Bun
Array.from(new Uint8Array(Bun.readableStreamToArrayBuffer(stream)));

يوفر Bun أداة دالة لحل ReadableStream إلى مصفوفة من قطعها. قد تكون كل قطعة سلسلة أو مصفوفة مكتوبة أو ArrayBuffer.

ts
// مع دالة Bun
Bun.readableStreamToArray(stream);

إلى Blob

ts
new Response(stream).blob();

إلى ReadableStream

لتقسيم ReadableStream إلى تيارين يمكن استهلاكهما بشكل مستقل:

ts
const [a, b] = stream.tee();

Bun بواسطة www.bunjs.com.cn تحرير