تحويل مصفوفة byte[] إلى Stream في C#: 4 طرق لإنقاذ مشروعك في 2025
\n\nتخيل: أنت تكتب تطبيقًا لمعالجة الصور، تقوم بتحميل ملف عبر طلب HTTP، وتستقبل مصفوفة بايت — وفجأة تكتشف أن مكتبتك المفضلة للتعامل مع PDF تتطلب Stream. هل هذا مألوف؟ إذا كنت تعمل مع C# و.NET، فستواجه عاجلاً أم آجلاً مهمة: "كيفية تحويل byte[] إلى Stream؟".
هذا السؤال على Stack Overflow حصد آلاف المشاهدات، وليس بدون سبب. قد يبدو الأمر بسيطًا، لكن الشيطان يكمن في التفاصيل: التحويل الخاطئ قد يؤدي إلى تسرب الذاكرة، انخفاض الأداء، أو الأسوأ من ذلك، تيارات غير مغلقة.
\n\nفي هذه المقالة، سنستعرض 4 طرق أفضل لتحويل byte[] إلى Stream في C#، المناسبة لعام 2025. ستتعلم ليس فقط "كيف تفعل ذلك"، بل أيضًا "لماذا هذه الطريقة بالذات"، وستحصل على مقتطفات جاهزة للاستخدام اليومي.
\n\nلماذا تحويل byte[] إلى Stream ليس مجرد "new MemoryStream(bytes)"؟
\n\nللوهلة الأولى، الحل واضح: MemoryStream هو تيار يعتمد على مصفوفة بايت. لكن دعنا نتعمق أكثر. في تطبيقات .NET الحديثة (خاصة في سياق البرمجة غير المتزامنة والتعامل مع البيانات الكبيرة)، اختيار الطريقة الخاطئة قد يكلفك أجزاءً ثمينة من الثانية أو حتى يؤدي إلى OutOfMemoryException.
إليك السيناريوهات الرئيسية التي قد تحتاج فيها إلى هذا التحويل:
\n- \n
- التعامل مع الملفات: قرأت ملفًا إلى
byte[](مثلًا عبرFile.ReadAllBytes)، وواجهة API للمكتبة تتطلبStream. \n - عمليات الشبكة: استقبلت مصفوفة بايت من استجابة HTTP، WebSocket، أو مقبس TCP. \n
- التشفير: طرق التشفير/فك التشفير غالبًا ما تعمل مع التدفقات، بينما لديك مصفوفة جاهزة. \n
- التسلسل: قمت بإلغاء تسلسل كائن إلى
byte[]، والآن تحتاج إلى تمريره إلى طريقة تنتظرStream. \n
الطريقة 1: MemoryStream الكلاسيكي (المستوى الأساسي)
\n\nأبسط وأسهل طريقة بديهية — إنشاء نسخة جديدة من MemoryStream وتمرير مصفوفة البايت إلى المُنشئ.
byte[] data = { 0x48, 0x65, 0x6C, 0x6C, 0x6F }; // "Hello" في ASCII\nusing (MemoryStream stream = new MemoryStream(data))\n{\n // الآن التيار جاهز للاستخدام\n // سيتم إغلاق التيار تلقائيًا عند الخروج من using\n Console.WriteLine($"طول التيار: {stream.Length} بايت");\n}\n\n\nالمزايا: البساطة، سهولة قراءة الكود، إدارة الذاكرة التلقائية عبر using.
العيوب: هل يتم إنشاء نسخة من البيانات؟ لا! ملاحظة مهمة: المُنشئ MemoryStream(byte[]) لا ينسخ المصفوفة، بل ينشئ تيارًا لا يدعم تغيير الحجم. سيعمل التيار مباشرة مع المصفوفة الأصلية. هذا سريع، لكن إذا حاولت توسيع التيار (مثلًا عبر SetLength)، فستحصل على استثناء NotSupportedException.
متى تستخدم: عندما تحتاج فقط إلى قراءة البيانات أو العمل بحجم ثابت. مثالي لتمرير البيانات إلى طرق تقبل Stream للقراءة فقط (مثلًا Image.FromStream).
الطريقة 2: MemoryStream مع إمكانية الكتابة (المستوى المتقدم)
\n\nإذا كنت بحاجة ليس فقط للقراءة من التيار، بل أيضًا للكتابة عليه، استخدم التحميل الزائد للمُنشئ مع العلامة writable.
byte[] data = { 0x41, 0x42, 0x43 }; // "ABC"\nbool writable = true;\nusing (MemoryStream stream = new MemoryStream(data, 0, data.Length, writable))\n{\n // الآن يمكنك ليس فقط القراءة، بل