كيفية تحويل ArrayBuffer إلى سلسلة ومنها

ريناتو مانجيني

تُستخدم برامج 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 هي في الواقع مصفوفة بايت، تتطلّب هذه الإحالة الناجحة أن يتفق الطرفان على كيفية تمثيل الأحرف في السلسلة كوحدات بايت. وربما تكون قد صادفت هذه "الاتفاقية" من قبل: إنها ترميز أحرف السلسلة (و"مصطلحات الاتفاقية" المعتادة هي، على سبيل المثال، Unicode 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 تتضمن السلسلة فيه. على الرغم من أن هذه الطريقة تعمل، إلا أنها سهلة القراءة وأظن أنها بطيئة. ونظرًا لأن الشكوك التي لا أساس لها من الصحة قد تسببت في العديد من الأخطاء في تاريخ الإنسانية، دعونا نتبع نهجًا أكثر علميًا هنا. لقد تعرّفت على الطريقتين وتأكّدت النتيجة من شكّي، ويمكنك الاطّلاع على العرض التوضيحي هنا.

في الإصدار 20 من Chrome، تزيد سرعة استخدام رمز معالجة ArrayBuffer المباشر الوارد في هذه المقالة بمقدار 27 مرة تقريبًا مقارنةً باستخدام طريقة FileReader/Blob.