تهدف هذه الصفحة إلى أن تكون مقدمة للعمل مع البيانات الثنائية في 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. |
BunFile | Bun فقط. فئة فرعية من Blob تمثل ملفاً يتم تحميله بشكل كسول على القرص. يتم إنشاؤها باستخدام Bun.file(path). |
ArrayBuffer والعروض
حتى عام 2009، لم تكن هناك طريقة أصلية في اللغة لتخزين والتلاعب بالبيانات الثنائية في JavaScript. قدم ECMAScript v5 مجموعة من الآليات الجديدة لهذا الغرض. لبنة البناء الأساسية هي ArrayBuffer، وهي بنية بيانات بسيطة تمثل سلسلة من البايتات في الذاكرة.
// هذا المخزن المؤقت يمكنه تخزين 8 بايتات
const buf = new ArrayBuffer(8);على الرغم من الاسم، فهو ليس مصفوفة ولا يدعم أي من طرق ومشغلات المصفوفة التي قد يتوقعها المرء. في الواقع، لا توجد طريقة لقراءة أو كتابة القيم مباشرة من ArrayBuffer. هناك القليل جداً الذي يمكنك فعله به باستثناء التحقق من حجمه وإنشاء "شرائح" منه.
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.
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.
dv.setUint16(1, 513);
// [0b00000011, 0b00000010, 0b00000001, 0b00000000]
console.log(dv.getUint16(1)); // => 513لقد قمنا الآن بتعيين قيمة للبايتات الثلاثة الأولى في ArrayBuffer الأساسي الخاص بنا. على الرغم من أن البايتات الثانية والثالثة تم إنشاؤها باستخدام setUint16()، لا يزال بإمكاننا قراءة كل بايت من مكوناتها باستخدام getUint8().
console.log(dv.getUint8(1)); // => 2
console.log(dv.getUint8(2)); // => 1محاولة كتابة قيمة تتطلب مساحة أكبر مما هو متاح في ArrayBuffer الأساسي ستسبب خطأ. فيما يلي نحاول كتابة Float64 (الذي يتطلب 8 بايتات) عند إزاحة البايت 0، ولكن هناك أربعة بايتات فقط في المجموع في المخزن المؤقت.
dv.setFloat64(0, 3.1415);
// ^ RangeError: Out of bounds accessالطرق التالية متاحة على DataView:
TypedArray
المصفوفات المكتوبة هي عائلة من الفئات التي توفر واجهة شبيهة بـ Array للتفاعل مع البيانات في ArrayBuffer. بينما يسمح لك DataView بكتابة أرقام بأحجام مختلفة عند إزاحة معينة، تفسر TypedArray البايتات الأساسية كمصفوفة من الأرقام، كل منها بحجم ثابت.
NOTE
من الشائع الإشارة إلى عائلة الفئات هذه بشكل جماعي بواسطة الفئة الفائقة المشتركة `TypedArray`. هذه الفئة _داخلية_ لـ JavaScript؛ لا يمكنك إنشاء مثيلات منها مباشرة، و`TypedArray` غير معرفة في النطاق العام. فكر فيها كـ `interface` أو فئة مجردة.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 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | |
|---|---|---|---|---|---|---|---|---|
ArrayBuffer | 00000000 | 00000001 | 00000010 | 00000011 | 00000100 | 00000101 | 00000110 | 00000111 |
Uint8Array | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Uint16Array | 256 (1 * 256 + 0) | 770 (3 * 256 + 2) | 1284 (5 * 256 + 4) | 1798 (7 * 256 + 6) | ||||
Uint32Array | 50462976 | 117835012 | ||||||
BigUint64Array | 506097522914230528n |
لإنشاء مصفوفة مكتوبة من ArrayBuffer محدد مسبقاً:
// إنشاء مصفوفة مكتوبة من 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، سنحصل على خطأ.
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 التي نريد أن تحتويها مصفوفتنا.
// إنشاء مصفوفة مكتوبة من شريحة 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 صراحة؛ يمكنك بدلاً من ذلك تحديد طول مباشرة في منشئ المصفوفة المكتوبة:
const arr2 = new Uint8Array(5);
// جميع العناصر مهيئة إلى الصفر
// => Uint8Array(5) [0, 0, 0, 0, 0]يمكن أيضاً إنشاء مثيلات المصفوفات المكتوبة مباشرة من مصفوفة من الأرقام، أو من مصفوفة مكتوبة أخرى:
// من مصفوفة من الأرقام
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 الأساسي.
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.
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".
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 worldBuffer
يطبق Bun Buffer، وهي واجهة برمجة تطبيقات Node.js للعمل مع البيانات الثنائية التي سبقت إدخال المصفوفات المكتوبة في مواصفات JavaScript. أعيد تنفيذها منذ ذلك الحين كفئة فرعية من Uint8Array. توفر مجموعة واسعة من الطرق، بما في ذلك عدة طرق شبيهة بالمصفوفة وDataView.
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" الثنائية أو السلسلة.
const blob = new Blob(["<html>Hello</html>"], {
type: "text/html",
});
blob.type; // => text/html
blob.size; // => 19يمكن أن تكون هذه الأجزاء string أو ArrayBuffer أو TypedArray أو DataView أو مثيلات Blob أخرى. يتم دمج أجزاء blob معاً بالترتيب الذي تم توفيرها به.
const blob = new Blob([
"<html>",
new Blob(["<body>"]),
new Uint8Array([104, 101, 108, 108, 111]), // "hello" بالثنائية
"</body></html>",
]);يمكن قراءة محتويات Blob بشكل غير متزامن بتنسيقات مختلفة.
await blob.text(); // => <html><body>hello</body></html>
await blob.bytes(); // => Uint8Array (ينسخ المحتويات)
await blob.arrayBuffer(); // => ArrayBuffer (ينسخ المحتويات)
await blob.stream(); // => ReadableStreamBunFile
BunFile هي فئة فرعية من Blob تُستخدم لتمثيل ملف يتم تحميله بشكل كسول على القرص. مثل File، تضيف خاصيتي name وlastModified. على عكس File، لا تتطلب تحميل الملف إلى الذاكرة.
const file = Bun.file("index.txt");
// => BunFileFile
File هي فئة فرعية من Blob تضيف خاصيتي name وlastModified. تُستخدم عادةً في المتصفح لتمثيل الملفات المرفوعة عبر عنصر <input type="file">. يطبق Node.js و Bun File.
// على المتصفح!
// <input type="file" id="file" />
const files = document.getElementById("file").files;
// => File[]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.لإنشاء تيار قابل للقراءة بسيط:
const stream = new ReadableStream({
start(controller) {
controller.enqueue("hello");
controller.enqueue("world");
controller.close();
},
});يمكن قراءة محتويات هذا التيار قطعة تلو الأخرى باستخدام صيغة for await.
for await (const chunk of stream) {
console.log(chunk);
}
// => "hello"
// => "world"لمناقشة أكثر اكتمالاً للتيارات في Bun، راجع API > Streams.
Conversion
التحويل من تنسيق ثنائي إلى آخر هو مهمة شائعة. يهدف هذا القسم إلى أن يكون مرجعاً.
من ArrayBuffer
بما أن ArrayBuffer يخزن البيانات التي تكمن وراء هياكل ثنائية أخرى مثل TypedArray، فإن المقاطع أدناه لا تحول من ArrayBuffer إلى تنسيق آخر. بدلاً من ذلك، هي تنشئ مثيلاً جديداً باستخدام البيانات المخزنة في البيانات الأساسية.
إلى TypedArray
new Uint8Array(buf);إلى DataView
new DataView(buf);إلى Buffer
// إنشاء Buffer على كامل ArrayBuffer
Buffer.from(buf);
// إنشاء Buffer على شريحة من ArrayBuffer
Buffer.from(buf, 0, 10);إلى string
كـ UTF-8:
new TextDecoder().decode(buf);إلى number[]
Array.from(new Uint8Array(buf));إلى Blob
new Blob([buf], { type: "text/plain" });إلى ReadableStream
المقطع التالي ينشئ ReadableStream ويضيف ArrayBuffer بالكامل كقطعة واحدة.
new ReadableStream({
start(controller) {
controller.enqueue(buf);
controller.close();
},
});مع التقطيع">
لبث ArrayBuffer في قطع، استخدم عرض Uint8Array وأضف كل قطعة.
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 يمكن أن تكون عرضاً لـ شريحة من المخزن المؤقت الأساسي، لذا قد تختلف الأحجام.
arr.buffer;إلى DataView
لإنشاء DataView على نفس نطاق البايتات مثل TypedArray.
new DataView(arr.buffer, arr.byteOffset, arr.byteLength);إلى Buffer
Buffer.from(arr);إلى string
كـ UTF-8:
new TextDecoder().decode(arr);إلى number[]
Array.from(arr);إلى Blob
// فقط إذا كان arr عرضاً لمصفوفة TypedArray الداعمة بالكامل
new Blob([arr.buffer], { type: "text/plain" });إلى ReadableStream
new ReadableStream({
start(controller) {
controller.enqueue(arr);
controller.close();
},
});مع التقطيع">
لبث ArrayBuffer في قطع، قسّم TypedArray إلى قطع وأضف كل واحدة بشكل فردي.
new ReadableStream({
start(controller) {
for (let i = 0; i < arr.length; i += chunkSize) {
controller.enqueue(arr.slice(i, i + chunkSize));
}
controller.close();
},
});من DataView
إلى ArrayBuffer
view.buffer;إلى TypedArray
تعمل فقط إذا كان byteLength لـ DataView هو مضاعف لـ BYTES_PER_ELEMENT لفئة TypedArray الفرعية.
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
Buffer.from(view.buffer, view.byteOffset, view.byteLength);إلى string
كـ UTF-8:
new TextDecoder().decode(view);إلى number[]
Array.from(view);إلى Blob
new Blob([view.buffer], { type: "text/plain" });إلى ReadableStream
new ReadableStream({
start(controller) {
controller.enqueue(view.buffer);
controller.close();
},
});مع التقطيع">
لبث ArrayBuffer في قطع، قسّم DataView إلى قطع وأضف كل واحدة بشكل فردي.
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
buf.buffer;إلى TypedArray
new Uint8Array(buf);إلى DataView
new DataView(buf.buffer, buf.byteOffset, buf.byteLength);إلى string
كـ UTF-8:
buf.toString();كـ base64:
buf.toString("base64");كـ hex:
buf.toString("hex");إلى number[]
Array.from(buf);إلى Blob
new Blob([buf], { type: "text/plain" });إلى ReadableStream
new ReadableStream({
start(controller) {
controller.enqueue(buf);
controller.close();
},
});مع التقطيع">
لبث ArrayBuffer في قطع، قسّم Buffer إلى قطع وأضف كل واحدة بشكل فردي.
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 طريقة راحة لهذا الغرض.
await blob.arrayBuffer();إلى TypedArray
await blob.bytes();إلى DataView
new DataView(await blob.arrayBuffer());إلى Buffer
Buffer.from(await blob.arrayBuffer());إلى string
كـ UTF-8:
await blob.text();إلى number[]
Array.from(await blob.bytes());إلى ReadableStream
blob.stream();من ReadableStream
من الشائع استخدام Response كتمثيل وسيط مناسب لتسهيل تحويل ReadableStream إلى تنسيقات أخرى.
stream; // ReadableStream
const buffer = new Response(stream).arrayBuffer();مع ذلك هذا النهج مطول ويضيف نفقات عامة تبطئ الأداء العام بشكل غير ضروري. يطبق Bun مجموعة من دوال الراحة المحسنة لتحويل ReadableStream إلى تنسيقات ثنائية مختلفة.
إلى ArrayBuffer
// مع Response
new Response(stream).arrayBuffer();
// مع دالة Bun
Bun.readableStreamToArrayBuffer(stream);إلى Uint8Array
// مع Response
new Response(stream).bytes();
// مع دالة Bun
Bun.readableStreamToBytes(stream);إلى TypedArray
// مع Response
const buf = await new Response(stream).arrayBuffer();
new Int8Array(buf);
// مع دالة Bun
new Int8Array(Bun.readableStreamToArrayBuffer(stream));إلى DataView
// مع Response
const buf = await new Response(stream).arrayBuffer();
new DataView(buf);
// مع دالة Bun
new DataView(Bun.readableStreamToArrayBuffer(stream));إلى Buffer
// مع Response
const buf = await new Response(stream).arrayBuffer();
Buffer.from(buf);
// مع دالة Bun
Buffer.from(Bun.readableStreamToArrayBuffer(stream));إلى string
كـ UTF-8:
// مع Response
await new Response(stream).text();
// مع دالة Bun
await Bun.readableStreamToText(stream);إلى number[]
// مع Response
const arr = await new Response(stream).bytes();
Array.from(arr);
// مع دالة Bun
Array.from(new Uint8Array(Bun.readableStreamToArrayBuffer(stream)));يوفر Bun أداة دالة لحل ReadableStream إلى مصفوفة من قطعها. قد تكون كل قطعة سلسلة أو مصفوفة مكتوبة أو ArrayBuffer.
// مع دالة Bun
Bun.readableStreamToArray(stream);إلى Blob
new Response(stream).blob();إلى ReadableStream
لتقسيم ReadableStream إلى تيارين يمكن استهلاكهما بشكل مستقل:
const [a, b] = stream.tee();