C++: عمليات الملفات المتقدمة

آخر تحديث: 2026-08-26

في الدرس 40 تعلمنا معالجة الاستثناءات.

الآن، سنتعمق في عمليات الملفات - مهارة أساسية للبيانات الدائمة في البرامج.

سواء كانت ملفات تهيئة أو سجلات أو قواعد بيانات، عمليات الملفات ضرورية.


1. نظرة عامة على تدفقات الملفات

(1) 1.1 فئات تدفق الملفات الثلاث

تستخدم C++ ثلاث فئات للتعامل مع الملفات:

الفئة الغرض
std::ifstream تدفق ملف إدخال (قراءة الملفات)
std::ofstream تدفق ملف إخراج (كتابة الملفات)
std::fstream تدفق ملف إدخال/إخراج (قراءة وكتابة)

(2) 1.2 فتح ملف

مثال: فتح ملف (الصعوبة ⭐)

▶ مثال 2: عرض عمليات الملف (الصعوبة ⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <fstream>

int main() {
 std::ifstream file("data.txt");
 
 if (!file) {
 std::cerr << "Unable to open file" << std::endl;
 return 1;
 }
 
 std::cout << "File opened successfully" << std::endl;
 file.close();
 
 return 0;
}

الخرج:

TEXT 📖 للعرض فقط
File opened successfully


2. قراءة وكتابة الملفات النصية

(1) 2.1 القراءة سطراً بسطر

مثال: عد أسطر الملف (الصعوبة ⭐)

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

int main() {
 std::ifstream file("data.txt");
 std::string line;
 int count = 0;
 
 while (std::getline(file, line)) {
 count++;
 }
 
 std::cout << "Number of lines: " << count << std::endl;
 file.close();
 
 return 0;
}

(2) 2.2 القراءة والكتابة المنسقتان

مثال: قراءة وكتابة بنية (الصعوبة ⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <fstream>

struct Student {
 char name[50];
 int age;
 double score;
};

int main() {
 Student s = {"Zhang San", 20, 85.5};
 
 // الكتابة إلى ملف
 std::ofstream out("student.txt");
 out << s.name << std::endl;
 out << s.age << std::endl;
 out << s.score << std::endl;
 out.close();
 
 // القراءة من ملف
 Student s2;
 std::ifstream in("student.txt");
 in >> s2.name >> s2.age >> s2.score;
 in.close();
 
 std::cout << "Name: " << s2.name << std::endl;
 std::cout << "Age: " << s2.age << std::endl;
 std::cout << "Score: " << s2.score << std::endl;
 
 return 0;
}

⚠️ تحذير:



3. الملفات الثنائية

(1) 3.1 لماذا نستخدم الملفات الثنائية؟

المقارنة ملف نصي ملف ثنائي
قابلية القراءة مقروء بشرياً غير مقروء
الحجم أكبر صغير
السرعة أبطأ سريع
عبر المنصات جيد ضعيف (مشاكل ترتيب البايتات)

(2) 3.2 قراءة وكتابة الملفات الثنائية

مثال: قراءة/كتابة ثنائية لبنية (الصعوبة ⭐⭐⭐)

CPP
#include <iostream>
#include <fstream>

struct Student {
 char name[50];
 int age;
 double score;
};

int main() {
 Student s = {"Zhang San", 20, 85.5};
 
 // كتابة ملف ثنائي
 std::ofstream out("student.bin", std::ios::binary);
 out.write(reinterpret_cast<char*>(&s), sizeof(s));
 out.close();
 
 // قراءة ملف ثنائي
 Student s2;
 std::ifstream in("student.bin", std::ios::binary);
 in.read(reinterpret_cast<char*>(&s2), sizeof(s2));
 in.close();
 
 std::cout << "Name: " << s2.name << std::endl;
 std::cout << "Age: " << s2.age << std::endl;
 std::cout << "Score: " << s2.score << std::endl;
 
 return 0;
}

💡 نصيحة:



4. الوصول العشوائي

(1) 4.1 seekg و seekp

الوصول العشوائي يسمح لك بالقفز إلى أي موضع في الملف للقراءة أو الكتابة.

الدالة الغرض
seekg(pos) تعيين موضع القراءة
seekp(pos) تعيين موضع الكتابة
tellg() الحصول على موضع القراءة الحالي
tellp() الحصول على موضع الكتابة الحالي

(2) 4.2 مثال: تعديل المحتوى في وسط الملف (الصعوبة ⭐⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <fstream>

int main() {
 std::fstream file("data.txt", std::ios::in | std::ios::out);
 
 // القفز إلى البايت العاشر
 file.seekp(10);
 
 // كتابة بيانات (الكتابة فوق)
 file << "Hello";
 
 file.close();
 return 0;
}

الخرج:

TEXT 📖 للعرض فقط
Hello, File!
C++ File Operations


5. حالة تدفق الملف

(1) 5.1 أعلام الحالة

لتدفقات الملفات 4 أعلام حالة:

العلم الوصف
good() كل شيء على ما يرام
eof() الوصول إلى نهاية الملف
fail() خطأ منطقي (مثلاً عدم تطابق النوع)
bad() خطأ جسيم (مثلاً فشل القرص)

(2) 5.2 مسح الحالة

مثال: معالجة نهاية الملف (الصعوبة ⭐)

CPP
#include <iostream>
#include <fstream>

int main() {
 std::ifstream file("data.txt");
 std::string line;
 
 while (true) {
 std::getline(file, line);
 
 if (file.eof()) {
 break; // الوصول إلى نهاية الملف
 }
 
 std::cout << line << std::endl;
 }
 
 file.clear(); // مسح الحالة للاستمرار في الاستخدام
 file.close();
 
 return 0;
}


6. تطبيق: قاعدة بيانات بسيطة

▶ مثال 1: إدارة سجلات الطلاب (الصعوبة ⭐⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

struct Student {
 int id;
 char name[50];
 int age;
};

void saveStudents(const std::vectorStudent& students, const std::string& filename) {
 std::ofstream file(filename, std::ios::binary);
 for (const auto& s : students) {
 file.write(reinterpret_cast<const char*>(&s), sizeof(s));
 }
}

void loadStudents(std::vectorStudent& students, const std::string& filename) {
 std::ifstream file(filename, std::ios::binary);
 Student s;
 while (file.read(reinterpret_cast<char*>(&s), sizeof(s))) {
 students.push_back(s);
 }
}

int main() {
 std::vector<Student> students = {
 {1, "Zhang San", 20},
 {2, "Li Si", 21}
 };
 
 // حفظ
 saveStudents(students, "students.bin");
 
 // تحميل
 std::vectorStudent loaded;
 loadStudents(loaded, "students.bin");
 
 std::cout << "Loaded " << loaded.size() << " records" << std::endl;
 
 return 0;
}

الخرج:

TEXT 📖 للعرض فقط
Loaded 2 records

▶ مثال 3: قراءة/كتابة ملف بسيط (الصعوبة ⭐)

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

int main() {
    // الكتابة إلى ملف
    std::ofstream outFile("test.txt");
    outFile << "Hello, File!" << std::endl;
    outFile << "C++ File Operations" << std::endl;
    outFile.close();
    
    // القراءة من ملف
    std::ifstream inFile("test.txt");
    std::string line;
    while (std::getline(inFile, line)) {
        std::cout << line << std::endl;
    }
    inFile.close();
    
    return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
(program output)

الخرج المتوقع:

TEXT 📖 للعرض فقط
Hello, File!
C++ File Operations

❓ أسئلة شائعة

س أيهما أفضل - الملفات النصية أم الثنائية؟
ج يعتمد على احتياجاتك: - تحتاج قابلية القراءة البشرية ← ملفات نصية - تحتاج كفاءة الأداء/المساحة ← ملفات ثنائية - تحتاج توافقاً عبر المنصات ← ملفات نصية

س كيف أتعامل مع المحارف العربية؟
ج دعم C++ لـ Unicode ضعيف. الاقتراحات: - احفظ الملفات النصية بترميز UTF-8 - استخدم مكتبات خارجية (مثل iconv) - أو التزم بالإنجليزية فقط

س ماذا لو تعذر فتح ملف؟
ج تحقق باستخدام if (!file)، مع معالجة الاستثناءات.

📖 ملخص

الموضوع النقاط الأساسية
فئات تدفق الملفات ifstream/ofstream/fstream
الملفات النصية العاملان << و >>
الملفات الثنائية write و read
الوصول العشوائي seekg/seekp
التحقق من الحالة eof()/fail()/bad()

📝 تمارين

  1. أساسي (الصعوبة ⭐): استخدم ofstream لكتابة ملف نصي (ثلاثة أسطر من المحتوى)، ثم استخدم ifstream لقراءته وعرضه على الشاشة.

  2. متوسط (الصعوبة ⭐⭐): استخدم fstream لفتح ملف بوضع ios::binary، اكتب مصفوفة من البنى، ثم اقرأها وتحقق منها.

  3. متقدم (الصعوبة ⭐⭐⭐): استخدم seekg/tellg لتطبيق وصول عشوائي للملفات. أنشئ "ملف فهرس" يسجل موضع كل سجل، مع دعم القفز المباشر إلى سجل محدد بالفهرس.



الدرس التالي: التعابير النمطية (#42)

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%