الدرس الثالث عشر: الملفات الثنائية (Binary Files) في لغة C
في هذا الدرس المتقدم، سنتناول بالتفصيل الملفات الثنائية في لغة C، خطوة بخطوة، مع شرح كامل للمبتدئين وأمثلة عملية وتمارين ومشاريع. ستتعلم كيفية التعامل مع الملفات لتخزين واسترجاع البيانات بطريقة فعالة وسريعة، بالإضافة إلى استخدام الهياكل والمصفوفات داخل الملفات.
1. مقدمة عن الملفات الثنائية
الملفات الثنائية (Binary Files) هي ملفات يتم تخزين البيانات فيها بصيغة بايتات، وليست نصوص قابلة للقراءة مباشرة. هذا النوع من الملفات يسمح بتخزين أنواع بيانات معقدة مثل الأعداد، الهياكل، والمصفوفات بشكل مباشر، مع سرعة أكبر وكفاءة أعلى مقارنة بالملفات النصية.
على سبيل المثال، إذا أردنا تخزين بيانات الطلاب مثل الاسم، العمر، والدرجات، فإن الملفات الثنائية تتيح حفظ كل هذه البيانات بشكل مضغوط وفعال.
2. مزايا استخدام الملفات الثنائية
- كفاءة في التخزين والقراءة والكتابة
- الحفاظ على تنسيق البيانات دون الحاجة لتحويلها إلى نص
- سهولة التعامل مع الهياكل والمصفوفات
- القدرة على إنشاء قواعد بيانات صغيرة وبرامج إدارة بيانات محلية
3. الدوال الأساسية للتعامل مع الملفات الثنائية
- fopen: فتح الملف للوصول إليه
- fclose: إغلاق الملف
- fwrite: كتابة بيانات
- fread: قراءة بيانات
- fseek: التحرك داخل الملف
- ftell: معرفة موقع المؤشر الحالي
4. فتح الملفات الثنائية
لفتح ملف ثنائي، نستخدم الدالة fopen مع الوضع المناسب:
- "rb" : قراءة فقط
- "wb" : كتابة فقط، سيتم مسح أي محتوى سابق
- "ab" : إضافة بيانات في نهاية الملف
- "r+b" : قراءة وكتابة
FILE *fp;
fp = fopen("data.bin", "wb"); // إنشاء ملف ثنائي جديد للكتابة
if(fp == NULL) {
printf("خطأ في فتح الملف\\n");
return 1;
}
5. كتابة البيانات إلى ملف ثنائي
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp = fopen("data.bin", "wb");
int numbers[5] = {10, 20, 30, 40, 50};
fwrite(numbers, sizeof(int), 5, fp); // كتابة المصفوفة كاملة
fclose(fp);
return 0;
}
6. قراءة البيانات من ملف ثنائي
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp = fopen("data.bin", "rb");
int numbers[5];
fread(numbers, sizeof(int), 5, fp); // قراءة المصفوفة
fclose(fp);
for(int i=0; i<5; i++)
printf("%d ", numbers[i]);
return 0;
}
7. استخدام الهياكل مع الملفات الثنائية
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[50];
int age;
};
int main() {
FILE *fp = fopen("students.bin", "wb");
struct Student s1 = {"Ali", 20};
struct Student s2 = {"Sara", 22};
fwrite(&s1, sizeof(struct Student), 1, fp);
fwrite(&s2, sizeof(struct Student), 1, fp);
fclose(fp);
return 0;
}
8. قراءة الهياكل من الملفات الثنائية
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[50];
int age;
};
int main() {
FILE *fp = fopen("students.bin", "rb");
struct Student s;
while(fread(&s, sizeof(struct Student), 1, fp)) {
printf("Name: %s, Age: %d\\n", s.name, s.age);
}
fclose(fp);
return 0;
}
9. التنقل داخل الملفات: fseek و ftell
fseek(fp, 0, SEEK_END); // الانتقال لنهاية الملف long size = ftell(fp); // معرفة حجم الملف fseek(fp, 0, SEEK_SET); // العودة لبداية الملف
10. تمارين عملية للمبتدئين
- كتابة برنامج لحفظ درجات الطلاب في ملف ثنائي واسترجاعها
- برنامج لإدارة مكتبة إلكترونية صغيرة
- برنامج لتخزين السجلات المالية وحساب المجموع
- تجربة تخزين مصفوفة من الأعداد العشرية بدلاً من الأعداد الصحيحة
- استخدام الهياكل لتخزين بيانات الموظفين وقراءتها لاحقًا
11. نصائح هامة
- ابدأ دائمًا بالملفات الصغيرة لتجنب الأخطاء
- تحقق دائمًا من نجاح فتح الملف قبل الكتابة أو القراءة
- حاول كتابة تعليقات توضح كل خطوة في البرنامج
- جرب تخزين أنواع بيانات مختلفة لتوسيع خبرتك