0Pricing
C++ Academy · درس

إدخال وإخراج الملفات الثنائية

اقرأ البايتات الخام واكتبها

إدخال وإخراج الملفات الثنائية درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

النصي مقابل الثنائي

يكتب الوضع النصي محارف مقروءة للبشر؛ أما الوضع الثنائي فيكتب البايتات الخام للكائنات تمامًا كما توجد في الذاكرة. افتحوا الملف باستخدام std::ios::binary.

#include <iostream>
#include <fstream>

int main() {
    int value = 12345;
    std::ofstream out("v.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&value), sizeof(value));
    std::cout << "wrote " << sizeof(value) << " bytes\n";
    return 0;
}

يأخذ write البايتات

تُخرج write(ptr, n) عدد n من البايتات الخام من ptr. وتحولون عنوان الكائن إلى const char*.

#include <iostream>
#include <fstream>

int main() {
    double d = 3.14;
    std::ofstream out("d.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&d), sizeof(d));
    out.close();
    std::cout << "saved a double\n";
    return 0;
}

يستعيد read البايتات

تُحمّل read(ptr, n) عدد n من البايتات في الكائن الموجود عند ptr، وبذلك تعكس عملية الكتابة الثنائية.

#include <iostream>
#include <fstream>

int main() {
    int original = 777;
    std::ofstream("i.bin", std::ios::binary).write(reinterpret_cast<const char*>(&original), sizeof(original));
    int loaded = 0;
    std::ifstream in("i.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&loaded), sizeof(loaded));
    std::cout << loaded << '\n';
    return 0;
}

كتابة بنية POD

يمكن تفريغ هياكل البيانات القديمة البسيطة (من دون مؤشرات وبأعضاء ذات أحجام ثابتة) وإعادة تحميلها ككتلة واحدة من البايتات.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record r{1, 99.5};
    std::ofstream out("rec.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(&r), sizeof(r));
    std::cout << "struct saved\n";
    return 0;
}

إعادة قراءة البنية

تُعيد القراءة البنية بأكملها في استدعاء واحد لـ read.

#include <iostream>
#include <fstream>

struct Record { int id; double balance; };

int main() {
    Record w{42, 250.0};
    std::ofstream("r2.bin", std::ios::binary).write(reinterpret_cast<const char*>(&w), sizeof(w));
    Record r{};
    std::ifstream in("r2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(&r), sizeof(r));
    std::cout << r.id << ' ' << r.balance << '\n';
    return 0;
}

كتابة مصفوفة

يمكنكم كتابة مصفوفة كاملة في استدعاء واحد، بتمرير إجمالي حجمها بالبايتات.

#include <iostream>
#include <fstream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    std::ofstream out("arr.bin", std::ios::binary);
    out.write(reinterpret_cast<const char*>(arr), sizeof(arr));
    std::cout << "wrote " << sizeof(arr) << " bytes\n";
    return 0;
}

إعادة قراءة المصفوفة

اقرؤوا العدد نفسه من البايتات في مصفوفة بالحجم نفسه.

#include <iostream>
#include <fstream>

int main() {
    int src[5] = {10, 20, 30, 40, 50};
    std::ofstream("a2.bin", std::ios::binary).write(reinterpret_cast<const char*>(src), sizeof(src));
    int dst[5] = {};
    std::ifstream in("a2.bin", std::ios::binary);
    in.read(reinterpret_cast<char*>(dst), sizeof(dst));
    for (int x : dst) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

تحديد مواضع القراءة والكتابة

يحرّك seekg (get) وseekp (put) موضع القراءة والكتابة، مما يتيح الوصول العشوائي إلى الملف.

#include <iostream>
#include <fstream>

int main() {
    int data[3] = {100, 200, 300};
    std::ofstream("seek.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("seek.bin", std::ios::binary);
    in.seekg(sizeof(int)); // skip to second int
    int second; in.read(reinterpret_cast<char*>(&second), sizeof(second));
    std::cout << second << '\n';
    return 0;
}

معرفة الموضع

يعرض tellg وtellp الموضع الحالي، وهو أمر مفيد لقياس حجم الملف أو الإزاحات.

#include <iostream>
#include <fstream>

int main() {
    int data[4] = {1, 2, 3, 4};
    std::ofstream("tell.bin", std::ios::binary).write(reinterpret_cast<const char*>(data), sizeof(data));
    std::ifstream in("tell.bin", std::ios::binary);
    in.seekg(0, std::ios::end);
    std::cout << "file size: " << in.tellg() << " bytes\n";
    return 0;
}

لماذا لا نستخدم المؤشرات؟

لا تفرغوا أبدًا الكائنات التي تحتوي على مؤشرات أو std::string بصيغة ثنائية؛ إذ ستحفظون عنوان المؤشر، لا البيانات التي يشير إليها. نفّذوا تسلسلًا للمحتويات بدلًا من ذلك.

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::string s = "hello";
    std::ofstream out("str.bin", std::ios::binary);
    std::size_t len = s.size();
    out.write(reinterpret_cast<const char*>(&len), sizeof(len));
    out.write(s.data(), len); // write the chars, not the object
    std::cout << "serialized " << len << " chars\n";
    return 0;
}

ملاحظات حول قابلية النقل

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

#include <iostream>
#include <cstdint>

int main() {
    std::int32_t fixed = 1; // fixed-width type for portability
    std::cout << "sizeof int32_t = " << sizeof(fixed) << '\n';
    return 0;
}

اختبار سريع

اختبروا فهمكم للإدخال والإخراج الثنائيين.

خلاصة

لقد تعلمتم الإدخال والإخراج الثنائيين للملفات:

  • افتحوا الملف باستخدام std::ios::binary؛ واستخدموا write/read مع reinterpret_cast<char*>
  • يتيح seekg/seekp وtellg/tellp الوصول العشوائي
  • لا تفرغوا المؤشرات أو السلاسل النصية مباشرةً؛ نفّذوا تسلسلًا لمحتوياتها، وانتبهوا إلى ترتيب البايتات

بعد ذلك، ستتعلمون التحقق من حالة الدفق والتعامل مع الأخطاء.

الأسئلة الشائعة

هل درس «إدخال وإخراج الملفات الثنائية» مجاني؟

نعم — نص درس «إدخال وإخراج الملفات الثنائية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «إدخال وإخراج الملفات الثنائية»؟

اقرأ البايتات الخام واكتبها تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «إدخال وإخراج الملفات الثنائية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. قراءة الملفات باستخدام ifstream
  2. كتابة الملفات باستخدام ofstream
  3. إدخال وإخراج الملفات الثنائية
  4. معالجة الأخطاء والحالة
← العودة إلى C++ Academy