التعامل مع الملفات في C++
معالجة الملفات في C++
التعامل مع الملفات أو معالجة الملفات ( Files Handling ) يقصد منها إجراء عملية ما على الملفات الموجودة في حاسوب المستخدم كقراءة محتوى ملف و عرضه في البرنامج, إنشاء نسخة منه, تعديل محتواه أو حذفه, سواء كان نوع الملف txt
, jpg
, mp4
أو أي نوع آخر.
الآن, للتعامل مع الملفات يجب تضمين الحزمة <fstream>
لأنها تحتوي على الكلاسات المخصصة لذلك, بالإضافة للحزمة <iostream>
لأننا سنحتاج منها العامل <<
عند الكتابة في الملف.
إذاً يجب كتابة هذين السطرين عند التعامل مع الملفات.
#include <iostream> #include <fstream>
مصطلحات تقنية هامة
إسم الحزمة
<fstream>
مشتق من جملة File Stream و التي تعني أنها مخصصة للتعامل مع الملفات.إسم الحزمة
<iostream>
مشتق من جملة Input Output Stream و التي تعني أنها تحتوي على أوامر الإدخال و الإجراج سواء على الشاشة أو في .
كلاسات الحزمة fstream
في C++
الحزمة <fstream>
تحتوي على الكلاسات الأساسية التالية التي يمكن استخدامها للتعامل مع الملفات.
الكلاس مع تعريفه | |
---|---|
ofstream
يستخدم لإنشاء كائن يتيح لنا إمكانية إنشاء ملف جديد و الكتابة فيه. |
|
ifstream
يستخدم لإنشاء كائن يتيح لنا إمكانية قراءة محتوى الملف. |
|
fstream
يستخدم لإنشاء كائن يتيح لنا إمكانية إنشاء ملف جديد, الكتابة فيه و القراءة منه أيضاً.إذاً هذا الكلاس يعتبر دمج للكلاس ofstream و الكلاس ifstream . |
طريقة فتح و إغلاق ملف في C++
إذا أردت قراءة محتوى ملف أو الكتابة فيه فلا بد من أن يكون مفتوحاً من قبل برنامجك نفسه حتى تتمكن من ذلك.
الكلاسات الثلاثة ifstream
و ofstream
و fstream
جميعها تحتوي على دالة إسمها open()
نستخدمها لنفتح الملف الذي نريد التعامل معه.
بناء الدالة open()
void open(const char *filename, ios::openmode mode)
مكان الباراميتر
filename
نمرر إسم و مسار الملف الذي نريد فتحه كنص عادي.mode
هو باراميتر إختياري يمكننا أن نمرر مكانه ثابت أو أكثر من الثوابت الجاهزة في الكلاسios
حتى نحدد للمترجم لماذا نريد فتح الملف.
في الجدول التالي وضعنا أسماء ثوابت الكلاس ios
التي يمكنك تمريرها مكان البارميتر mode
.
الثابت مع تعريفه | |
---|---|
ios::app
يستخدم لإعلام المترجم بأن المحتوى الجديد الذي سيتم إضافته سيوضع في آخر الملف. |
|
ios::ate
يستخدم لإعلام المترجم بأن سيتم فتح الملف بهدف الكتابة و القراءة منه مع الإشارة إلى أنه سيبدأ من آخره. |
|
ios::in
يستخدم لإعلام المترجم بأنه سيتم فتح الملف بهدف القراءة منه. |
|
ios::out
يستخدم لإعلام المترجم بأنه سيتم فتح الملف بهدف الكتابة فيه. |
|
ios::trunc
يستخدم لإعلام المترجم بأنه في حال كان الملف موجود مسبقاً, سيتم مسح محتواه عند فتحه. |
عند استدعاء الدالة open()
يمكنك استخدام العامل |
في حال أردت أن تمرر لها أكثر من قيمة مكان البارميتر mode
كالتالي.
ofstream myfile; myfile.open ("example.txt", ios::out | ios::app);
معلومة تقنية مهمة جدا
الكلاس
ofstream
يستخدم الثابتios::out
بشكل إفتراضي.الكلاس
ifstream
يستخدم الثابتios::in
بشكل إفتراضي.الكلاس
fstream
يستخدم الثابتينios::in | ios::out
بشكل إفتراضي.
أهمية إغلاق الملف عند الإنتهاء منه في C++
عند الإنتهاء من التعامل مع أي ملف, قم بإغلاقه على الفور لأن ذلك من شأنه تحسين أداء البرنامج حيث سيخفف من حجم المساحة المحجوزة للملف في الذاكرة بالإضافة إلى أنك تصبح قادر على التعامل مع هذا الملف بشكل مباشر من خارج برنامجك.
الكلاسات الثلاثة ifstream
و ofstream
و fstream
جميعها تحتوي على دالة إسمها close()
نستخدمها لإغلاق الملف.
إذاً لإغلاق الإتصال مع أي ملف مفتوح, يجب أن تستدعي الدالة close()
من الكائن الذي بالأساس فتحت الملف من خلاله.
التشييك على حالة الكائن الذي نتعامل من خلاله مع الملف في C++
عند استخدام الدالة open()
لفتح الملف سواء بهدف القراءة أو الكتابة فيه فإن ذلك قد لا ينجح دائماً.
فمثلاً إذا كنت تريد إنشاء ملف جديد, قد تكون لا تملك صلاحية لإنشاء ملف في الحاسوب أو لا يوجد مساحة كافية لإنشاء الملف فيها, أو أن الملف موجود أصلاً و لكنه مفتوح من قبل برنامج آخر. و في حال كنت تريد قراءة محتوى ملف موجود في الحاسوب قد تواجه أيضاً بعض المشاكل, كأن يكون مسار الملف الموضوع غير صحيح, أو أن الملف مفتوح من قبل برنامج آخر أو أنك لا تملك صلاحية للقراءة منه إلخ..
بعد إنشاء الكائن الذي ستتعامل من خلاله مع الملف, يمكنك استخدام الجمل الشرطية if
و else
بكل سهولة كالتالي لمعرفة ما إن كان يمكنك التعامل مع الملف أم لا.
ofstream myfile; myfile.open ("example.txt"); if (myfile) { // إذا كان الإتصال بالملف لا يوجد فيه مشاكل, سيتم تنفيذ الأوامر التي نضعها هنا } else { // إذا أردت إعلام المستخدم بأنه حدث مشكلة أثناء الإتصال بالملف, فيمكنك كتابة ذلك هنا }
هناك 4 دوال جاهزة يمكنك استخدامها للتأكد من أن الإتصال بالملف سليم و أنه لم تحدث أي مشكلة عند التعامل معه سواء عند القراءة أو الكتابة فيه.
إسم الدالة مع تعريفها | |
---|---|
bool bad()
تستخدم لمعرفة ما إن حصلت أي مشكلة عند القراءة أو الكتابة في الملف.ترجع true إذا حدثت مشكلة و ترجع false إذا لم تحدث أي مشكلة.من المشاكل التي نقصدها كأن تحاول الكتابة في الملف و لكنه لا يوجد مساحة كافية للتخزين, أو في حال فتحت ملف بواسطة كائن من ofstream و لكنك كنت تنوي استخدامه للقراءة و ليس للكتابة. في هذه الحالات يمكنك الإستفادة من هذه الدالة لمعرفة ما إن حدث خطأ أم لا. |
|
bool fail()
مثل الدالة bad() تماماً بالإضافة إلى أنها تشيك على المشاكل التي قد تحدث عند التعامل مع محتوى الملف.على سبيل المثال, إذا قمت بقراءة عدد مخزن في الملف و قمت بقراءته في برنامجك و من ثم التعامل معه كأنه عدد عادي بدون أن تحوله لعدد ستجد أنها تنبهك عن هذا الخطأ أيضاً. ترجع true إذا حدثت مشكلة و ترجع false إذا لم تحدث أي مشكلة. |
|
bool eof()
إسم الدالة هو اختصار لجملة End Of File و هي تستخدم لمعرفة ما إن وصلت في القراءة أو الكتابة إلى آخر الملف أم لا.ترجع true إذا كان المترجم وصل لنهاية الملف و ترجع false إذا يصل بعد لنهايته. |
|
bool good()
تستخدم لمعرفة ما إن حصلت أي مشكلة كانت عند التعامل مع الملف و هي تشمل كل أنواع المشاكل التي قد تحدث.ترجع true إذا لم تحدث أي مشكلة و ترجع false إذا حدثت مشكلة ما. |
الكلاسات الثلاثة ifstream
و ofstream
و fstream
جميعها تحتوي على هذه الدوال و ستجد كيفية استخدامها لاحقاً في الأمثلة.
أمثلة شاملة على التعامل مع الملفات في C++
كيفية إنشاء ملف جديد في الحاسوب و الكتابة فيه بواسطة كائن من الكلاس ofstream
.
هنا وضعنا مثال حول كيفية إنشاء ملف جديد في الحاسوب و الكتابة فيه بواسطة كائن من الكلاس ofstream
.
في المثال التالي قمنا بإنشاء ملف نصي جديد إسمه demo.txt
في نفس المشروع الذي نعمل فيه.
بعدها قمنا بالتأكد من أنه قد تم إنشاء الملف بنجاح و من ثم كتابة سطرين بداخله.
مثال
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لإنشاء ملف جديد و الكتابة فيه outfile إسمه ofstream هنا قمنا بإنشاء كائن من الكلاس ofstream outfile; // و فتحه "demo.txt" لإنشاء ملف جديد إسمه open() هنا قمنا باستدعاء الدالة outfile.open("demo.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه outfile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(outfile) { // outfile هنا قمنا بإضافة نص في الملف الذي يشير إليه الكائن outfile << "This is a line.\n"; outfile << "This is another line.\n"; } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة outfile من الكائن close() هنا قمنا باستدعاء الدالة outfile.close(); return 0; }
•عند تشغيل البرنامج سيتم إنشاء ملف إسمه demo.txt
في نفس المشروع الذي نعمل فيه و بداخله النص التالي.
This is a line. This is another line.
•بعد أن قمنا بتشغيل البرنامج, قمنا بفتح مجلد المشروع للتأكد من أن الملف demo.txt
قم تم إنشاؤه فعلاً فيه.
كيفية قراءة محتوى ملف موجود في الحاسوب و عرضه في البرنامج بواسطة كائن من الكلاس ifstream
.
هنا وضعنا مثال حول كيفية قراءة محتوى ملف موجود في الحاسوب و عرضه في البرنامج بواسطة كائن من الكلاس ifstream
.
ملاحظة: سنقوم بقراءة محتوى الملف الذي أنشأناه في المثال السابق.
في المثال التالي قمنا بقراءة محتوى الملف demo.txt
الذي أنشأناه في المثال السابق في نفس المشروع الذي نعمل فيه.
بعدها قمنا بعرض محتوى الملف في البرنامج, أي في الكونسول.
مثال
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لقراءة محتوى ملف موجود في الحاسوب infile إسمه ifstream هنا قمنا بإنشاء كائن من الكلاس ifstream infile; // "demo.txt" لفتح الملف open() هنا قمنا باستدعاء الدالة infile.open("demo.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه infile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(infile) { // سنستخدم هذا المتغير لتخزين كل سطر جديد نقوم بجلبه من الملف فيه بشكل مؤقت قبل عرضه string line; // line تجد سطر جديد, ستقوم بوضعه بشكل مؤقت في المتغير getline() طالما أن الدالة while هنا في كل دورة من دورات الحلقة while (getline (infile, line)) { // بعدها سنقوم بعرضه و النزول على سطر جديد حتى لا يظهر كل محتوى الملف على سطر واحد cout << line << endl; } } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة infile من الكائن close() هنا قمنا باستدعاء الدالة infile.close(); return 0; }
•عند تشغيل البرنامج سيتم عرض محتوى الملف demo.txt
كالتالي.
This is a line. This is another line.
كيفية إنشاء ملف و الكتابة فيه و من ثم قراءة محتواه بواسطة كائن من الكلاس fstream
هنا وضعنا مثال حول كيفية إنشاء ملف و الكتابة فيه و من ثم قراءة محتواه بواسطة كائن من الكلاس fstream
.
في المثال التالي قمنا بإنشاء ملف نصي جديد إسمه demo.txt
في نفس المشروع الذي نعمل فيه.
بعدها قمنا بالتأكد من أنه قد تم إنشاء الملف بنجاح و من ثم كتابة سطرين بداخله.
بعدها قمنا بالرجوع لبداية الملف باستخدام الدالة seekg()
مع تمرير القيمة 0
لها للإشارة إلى أول حرف موجود في الملف.
بعدها قمنا بقراءة النص الذي أضفناه في الملف منه و عرضه في البرنامج, أي في الكونسول.
مثال
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لإنشاء ملف جديد و الكتابة فيه file إسمه fstream هنا قمنا بإنشاء كائن من الكلاس fstream file; // و فتحه "demo.txt" لإنشاء ملف جديد إسمه open() هنا قمنا باستدعاء الدالة file.open("demo.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه file هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(file) { // file هنا قمنا بإضافة نص في الملف الذي يشير إليه الكائن file << "This is a line.\n"; file << "This is another line.\n"; // هنا قمنا بالرجوع لأول الملف لأننا سنقوم بقراءة محتواه من البداية file.seekg(0); // سنستخدم هذا المتغير لتخزين كل سطر جديد نقوم بجلبه من الملف فيه بشكل مؤقت قبل عرضه string line; // line تجد سطر جديد, ستقوم بوضعه بشكل مؤقت في المتغير getline() طالما أن الدالة while هنا في كل دورة من دورات الحلقة while (getline (file, line)) { // بعدها سنقوم بعرضه و النزول على سطر جديد حتى لا يظهر كل محتوى الملف على سطر واحد cout << line << endl; } } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة file من الكائن close() هنا قمنا باستدعاء الدالة file.close(); return 0; }
•عند تشغيل البرنامج سيتم عرض محتوى الملف demo.txt
كالتالي.
This is a line. This is another line.
كيفية إضافة نص في آخر النص الموجود في الملف بواسطة كائن من الكلاس ofstream
و الثابت ios::app
.
هنا وضعنا مثال حول كيفية إضافة نص في آخر النص الموجود في الملف بواسطة كائن من الكلاس ofstream
و الثابت ios::app
.
ملاحظة: عند محاولة الإتصال بالملف لن يتم إنشاؤه من جديد في حال كان في الأساس موجوداً.
في المثال التالي قمنا بتمرير الثابت ios::app
للدالة open()
لإعلام المترجم بأننا نريد فتح ملف إسمه append.txt
موجود في نفس المشروع الذي نعمل فيه بهدف إضافة نص في آخره و في حال لم يكن موجوداً فإننا نريد إنشاؤه و فتحه أيضاً لذات الهدف.
بعدها قمنا بالتأكد من أن الملف موجود و لا يوجد أي مشكلة في الإتصال به, و من ثم إضافة سطر على المحتوى الموجود فيه.
مثال
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لإنشاء ملف جديد و الكتابة فيه outfile إسمه ofstream هنا قمنا بإنشاء كائن من الكلاس ofstream outfile; // للدالة ios::app و في حال لم يكن موجوداً سيتم إنشاؤه و فتحه لأننا مررنا الثابت "append.txt" لفتح ملف إسمه open() هنا قمنا باستدعاء الدالة outfile.open("append.txt", ios::app); // لا يوجد فيه أي مشاكل قبل التعامل معه outfile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(outfile) { // outfile هنا قمنا بإضافة نص في الملف الذي يشير إليه الكائن outfile << "This is a new line added at the end.\n"; } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة outfile من الكائن close() هنا قمنا باستدعاء الدالة outfile.close(); return 0; }
•عند تشغيل البرنامج سيتم إنشاء ملف إسمه append.txt
في نفس المشروع الذي نعمل فيه و بداخله النص التالي.
This is a new line added at the end.
•قم بإغلاق الملف append.txt
إذا كنت قد فتحته, ثم قم بتشغيل البرنامج مرة ثانية و لاحظ كيف سيتم إضافة النص "This is a new line added at the end."
من جديد في آخره كالتالي.
This is a new line added at the end. This is a new line added at the end.
ننصحك بإغلاق الملف append.txt
و تغيير النص الذي وضعناه في السطر 18
لأي نص تريد و من ثم تشغيل البرنامج لملاحظة كيف سيتم إضافة النص الذي كتبته أنت في آخر الملف.
كيفية إضافة نص في أول النص الموجود في الملف بواسطة كائن من الكلاس ofstream
و الثابت ios::app
.
هنا وضعنا مثال حول كيفية إضافة نص في أول النص الموجود في الملف بواسطة كائن من الكلاس ofstream
و الثابت ios::app
.
ملاحظة: عند محاولة الإتصال بالملف لن يتم إنشاؤه من جديد في حال كان في الأساس موجوداً.
لإضافة نص في أول الملف بدون حذف باقي المحتوى الموجود فيه, يجب أن نقرأ محتوى الملف و نخزّنه بشكل مؤقت في متغير نصي.
بعدها نقوم بحذف الملف الأصلي.
بعدها نقوم بإنشاء ملف جديد فارغ بنفس إسم الملف الأصلي.
في الأخير نقوم بإضافة النص الجديد في الملف الجديد و يليه النص الذي قمنا بتخزينه في المتغير.
يمكنك فعل هذا الأمر بطريقة أخرى إن أردت حيث أنك تستطيع إنشاء ملف جديد تضع فيه النص الذي تريد إضافته في الملف.
بعدها تقرأ محتوى الملف الأصلي و تضيفه فيه.
في المثال التالي قمنا بتطبيق الطريقة الأولى التي يمكن استخدامها لإضافة نص في أول الملف.
لأجل هذا الأمر قمنا بإنشاء كائن من الكلاس ifstream
لقراءة محتوى الملف الأصلي الذي نريد إضافة نص في أوله.
و كائن من الكلاس ofstream
لإنشاء ملف جديد بنفس الإسم و إضافة النص الجديد فيه و يليه النص الذي كان موجوداً في الملف الأصلي.
مثال
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنتخدمه لقراءة محتوى ملف موجود في الحاسوب infile إسمه ifstream هنا قمنا بإنشاء كائن من الكلاس // لأننا سنتخدمه للكتابة في نفس الملف السابق outfile إسمه ofstream و قمنا بإنشاء كائن من الكلاس // سنضع فيه النص الذي نقرؤه من الملف بشكل مؤقت data المتغير // وضعنا فيه النص الذي ننوي إضافته في بداية الملف على سطر خاص textToAdd المتغير ifstream infile; ofstream outfile; string data; string textToAdd = "This is a new line added at the begining.\n"; // "prepend.txt" لفتح ملف إسمه open() هنا قمنا باستدعاء الدالة infile.open("prepend.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه infile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(infile) { // سنستخدم هذا المتغير لتخزين كل سطر جديد نقوم بجلبه من الملف فيه بشكل مؤقت قبل عرضه string line; // line تجد سطر جديد, ستقوم بوضعه بشكل مؤقت في المتغير getline() طالما أن الدالة while هنا في كل دورة من دورات الحلقة while (getline (infile, line)) { // data في المتغير line بعدها سيتم إضافة السطر الذي تم وضعه بشكل مؤقت في المتغير data += line + "\n"; } // data عند انتهاء الحلقة سيكون كل محتوى الملف قد تم وضعه في المتغير } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة infile من الكائن close() هنا قمنا باستدعاء الدالة infile.close(); // بدل الملف القديم و فتحه أيضاً"prepend.txt" لإنشاء ملف جديد إسمه open() هنا قمنا باستدعاء الدالة outfile.open("prepend.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه outfile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(outfile) { // outfile في الملف الجديد الذي يشير إليه الكائن textToAdd هنا قمنا بإضافة النص الموجود في المتغير outfile << textToAdd; // أيضاً outfile الذي قمنا بنسخه من الملف الأصلي في الملف الذي يشير إليه الكائن data بعدها قمنا بإضافة النص الموجود في المتغير outfile << data; } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة outfile من الكائن close() هنا قمنا باستدعاء الدالة outfile.close(); return 0; }
•عند تشغيل البرنامج سيتم إنشاء ملف إسمه prepend.txt
في نفس المشروع الذي نعمل فيه و بداخله النص التالي.
This is a new line added at the begining.
•قم بإغلاق الملف prepend.txt
إذا كنت قد فتحته, ثم قم بتشغيل البرنامج مرة ثانية و لاحظ كيف سيتم إضافة النص "This is a new line added at the begining."
من جديد في أوله كالتالي.
This is a new line added at the begining. This is a new line added at the begining.
ننصحك بإغلاق الملف prepend.txt
و تغيير النص الذي وضعناه في المتغير textToAdd
لأي نص تريد و من ثم تشغيل البرنامج لملاحظة كيف سيتم إضافة النص الذي كتبته أنت في أول الملف.
كيفية حذف ملف من الحاسوب باستخدام الدالة remove()
بالإضافة إلى كيفية طباعة الأخطاء التي قد تحدث عند محاولة حذف الملف
هنا وضعنا مثال حول كيفية حذف ملف من الحاسوب باستخدام الدالة remove()
بالإضافة إلى كيفية طباعة الأخطاء التي قد تحدث عند محاولة حذف الملف.
الدالة remove()
لحذف ملف من الحاسوب نستخدم دالة جاهزة إسمها remove()
موجودة في الأساس في الحزمة <iostream>
و هي معرفة كالتالي.
int remove(const char* filename)
إذاً عند استدعاءها يجب أن نمرر لها إسم أو مسار الملف الذي نريد حذفه كمصفوفة أحرف أو كمؤشر لها فترجع عدد أكبر من 0
إذا قامت بحذف الملف بنجاح و إن فشلت في حذف الملف لأي سبب كان فإنها ترجع 0
.
إذاً في حال قامت الدالة remove()
بإرجاع القيمة 0
فهذا دليل على أنها لم تستطع حذف الملف.
في المثال التالي حاولنا حذف ملف إسمه demo.txt
إفترضنا أنه موجود في نفس المشروع الذي نعمل فيه.
بعدها قمنا بطباعة ما إن كان الملف قد تم حذفه أم لا.
مثال
#include <iostream> using namespace std; int main() { // fileName هنا قمنا بتخزين إسم الملف الذي نريد حذفه في مصفوفة الأحرف char fileName[] = "demo.txt"; // fileName لمحاولة حذف الملف الموجود إسمه في المصفوفة remove() هنا قمنا باستدعاء الدالة // لمعرفة ما إن كانت قد حذفت الملف أم لا remove() ثم قمنا بالتشييك على القيمة التي سترجعها الدالة if (remove(fileName) != 0) { // في حال لم يتم حذف الملف سيتم طباعة الجملة التالية, ثم نطقتين فوق بعضهما, ثم سبب الخطأ الذي حدث perror("File deletion failed"); } else { // في حال لم تم حذف الملف بنجاح سيتم تنفيذ أمر الطباعة التالي الذي يعني أنه تم حذف الملف بنجاح cout << "File deleted successfully"; } return 0; }
•عند تشغيل البرنامج, إذا كان يوجد في مشروعك ملف إسمه demo.txt
سيتم حذفه و طباعة الجملة التالية.
File deleted successfully
•عند تشغيل البرنامج, إذا كان لا يوجد في مشروعك ملف إسمه demo.txt
سيتم طباعة الجملة التالية.
File deletion failed: No such file or directory
كيفية استخدام الدوال bad()
و fail()
و eof()
و good()
للتشييك على حالة الكائن المستخدم للتعامل مع الملف
هنا وضعنا مثال حول كيفية استخدام الدوال bad()
و fail()
و eof()
و good()
للتشييك على حالة الكائن المستخدم للتعامل مع الملف.
في المثال التالي قمنا بإنشاء كائن من الكلاس ifstream
و من ثم حاولنا استخدامه لقراءة محتوى ملف إسمه demo.txt
.
إذاً هنا قد تحدث مشكلة في حال لم يكن هناك ملف في المشروع إسمه demo.txt
و ستحدث مشكلة حتماً عند محاولة قراءة محتوى الملف لأن الكلاس ifstream
مصمم للكتابة في الملف و ليس القراءة منه.
بعدها قمنا بالتشييك على حالة الكائن لمعرفة ما إن حدثت مشكلة عند التعامل مع الملف أم لا.
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لقراءة محتوى ملف موجود في الحاسوب infile إسمه ifstream هنا قمنا بإنشاء كائن من الكلاس ifstream infile; // مع العلم أنه لا يوجد ملف بهذا الإسم في المشروع "harmash.txt" لفتح ملف إسمه open() هنا قمنا باستدعاء الدالة infile.open("harmash.txt"); // هنا سيتم طباعة ما إن كنا قد فتحنا الملف و قرأنا الأحرف الموجودة فيه وصولاً لآخر حرف أم لا if (infile.eof()) { cout << "You reach the end of file.\n"; } else { cout << "You didn't reach the end of file.\n"; } // هنا سيتم طباعة أي مشكلة حدثت عند محاولة التعامل مع الملف if (infile.good()) { cout << "No problem happed till now."; } else { // ثم نطقتين فوق بعضهما, ثم سبب الخطأ الذي حدث "Error" سيتم طباعة كلمة perror("Error"); } // لإغلاق الإتصال مع الملف في حال كان قد تم فتحه أصلاً infile من الكائن close() هنا قمنا باستدعاء الدالة infile.close(); return 0; }
•سنحصل على النتيجة التالية عند التشغيل.
You didn't reach the end of file. Error: No such file or directory
كيفية معرفة حجم الملف مهما كان نوعه.
هنا وضعنا مثال حول كيفية معرفة حجم الملف مهما كان نوعه.
لمعرفة حجم الملف مهما كان نوعه تحتاج التالي:
إجمالاً Index آخر حرف في الملف يساوي حجم الملف.
لمعرفة Index الحرف الذي يقف عنده المترجم حالياً نستخدم دالة جاهزة إسمها
tellg()
.للإنتقال من أول حرف في الملف لآخر حرف فيه نستخدم الدالة
seekg(0, ios::end)
.
في المثال التالي قمنا بإنشاء كائن من الكلاس ifstream
و من ثم حاولنا استخدامه لقراءة محتوى ملف إسمه demo.txt
.
بعد التأكد من أن الملف مفتوح, قمنا بتخزين Index أول حرف في الملف في متغير إسمه begin
و آخر حرف في الملف في متغير إسمه end
لأننا من خلال طرحهما من بعضهما سنعرف حجم الملف.
#include <iostream> #include <fstream> using namespace std; int main() { // آخر حرف في الملف index لتخزين end سنستخدم المتغير streampos end; // لأننا سنستخدمه لقراءة محتوى ملف موجود في الحاسوب myFile إسمه ifstream هنا قمنا بإنشاء كائن من الكلاس ifstream myFile; // إفترضنا أنه موجود في المشروع "demo.txt" لفتح ملف إسمه open() هنا قمنا باستدعاء الدالة myFile.open("demo.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه myFile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(myFile) { // لها لجعل المترجم يتوجه لآخر حرف موجود في الملف ios::end و تمرير الثابت seekg() هنا قمنا باستدعاء الدالة myFile.seekg(0, ios::end); // end الحرف الحالي الذي يقف عنده المترجم في الذاكرة و من ثم تخزينه في المتغير index لتخزين tellg() هنا قمنا باستدعاء الدالة end = myFile.tellg(); // آخر حرف في الملف و الناتج سيكون حجم الملف index هنا قمنا بطباعة cout << "Size is: " << end << " bytes."; } else { // ثم نطقتين فوق بعضهما, ثم سبب الخطأ الذي حدث "Error" في حال وجود خطأ سيتم طباعة كلمة perror("Error"); } // لإغلاق الإتصال مع الملف في حال كان قد تم فتحه أصلاً myFile من الكائن close() هنا قمنا باستدعاء الدالة myFile.close(); return 0; }
•عند تشغيل البرنامج, إذا كان يوجد في مشروعك ملف إسمه demo.txt
سيتم طباعة حجمه كالتالي مع الإشارة إلى أن حجم الملف سيكون بقدر حجم ملفك الحقيقي.
Size is: 95 bytes.
•عند تشغيل البرنامج, إذا كان لا يوجد في مشروعك ملف إسمه demo.txt
سيتم طباعة الجملة التالية.
Error: No such file or directory
كيفية إنشاء نسخة من ملف غير نصي (Binary File) مثل الملفات الصوتية و الفيديوهات إلخ..
هنا وضعنا مثال حول كيفية إنشاء نسخة من ملف غير نصي (Binary File) مثل الملفات الصوتية و الفيديوهات إلخ..
ملاحظة: الملفات الغير نصية نتعامل معها بطريقة خاصة.
يوجد طرق خاصة للتعامل مع الملفات الغير نصية مما يجعل عملية التعامل معها أسرع و أكثر كفاءة.
إذاً لن نستخدم الرموز >>
و <<
أو الدالة getline()
عند التعامل مع ملفات غير نصية.
الآن, لقراءة محتوى ملف غير نصي نستخدم دالة جاهزة إسمها read()
و للكتابة في ملف غير نصي نستخدم دالة جاهزة إسمها write()
.
الدالة
read()
ترجع لك محتوى الملف كمصفوفة أحرف.الدالة
write()
تمرر لها المحتوى الذي تريد كتابته في الملف كمصفوفة أحرف أيضاً.
بناء الدالتين read()
و write()
:
char* write ( char* memory_block, int size ) char* read ( char* memory_block, int size )
في المثال التالي قمنا بإنشاء كائن من الكلاس ifstream
لنقرأ محتوى ملف إسمه D:/files/logo.PNG
و من ثم إنشاء نسخة منه بواسطة كائن من الكلاس ofstream
إسمها logo-copy.PNG
في نفس المجلد الذي يوجد فيه الملف الأصلي.
ملاحظة: نحن إفترضنا أنه على الحاسوب يوجد ملف إسمه logo.PNG
في مجلد إسمه files
في القرص D
.
إذا كنت ستجرب الكود التالي لا تنسى وضع مسار الملف الذي تريد إنشاء نسخة منه بشكل صحيح نسبةً لك أنت.
#include <iostream> #include <fstream> using namespace std; int main() { // بشكل أساسي لأننا سنستخدمه لحجز مساحة في الذاكرة من أجل وضع المحتوى فيها size هنا قمنا بتجهيز المتغير streampos size; // عبارة عن مصفوفة و سنستخدمها لتخزين الأحرف التي نقرأها من الملف الذي نريد إنشاء نسخة منه memblock char* memblock; // مع تحديد أننا سنستخدمه لقراءة محتوى ملف غير نصي و جعل المترجم يقف عند آخر حرف موجود فيه عند التعامل معه بالإضافة إلى فتحه ifstream هنا قمنا بإنشاء كائن من الكلاس ifstream infile ("D:/files/logo.PNG", ios::in|ios::binary); // مع تحديد أننا سنستخدمه لإنشاء ملف غير نصي و الكتابة فيه بالإضافة إلى فتحه ofstream هنا قمنا بإنشاء كائن من الكلاس ofstream outfile ("D:/files/logo.PNG", ios::binary|ios::out); // هنا قمنا بالتأكد من أن كلا الملفين مفتوحين و يمكن التعامل معهما if (infile.is_open() && outfile.is_open()) { // لها لجعل المترجم يتوجه لآخر حرف موجود في الملف ios::end و تمرير الثابت seekg() هنا قمنا باستدعاء الدالة infile.seekg(0, ios::end) // size آخر حرف في الملف لأنه سيمثل حجمه في المتغير index هنا سيتم تخزين size = infile.tellg(); // size في الذاكرة مع تحديد أن عدد الأحرف التي سنضعها فيها يساوي عدد الأحرف الموجودة في الملف و الذي قمنا بتخزينه في المتغير memblock هنا قمنا بتحديد بإنشاء المصفوفة memblock = new char [size]; // هنا قمنا بالرجوع لأول حرف موجود في الملف الأصلي حتى نتمكن من قراءة كل محتواه infile.seekg (0, ios::beg); // memblock هنا قمنا بقراءة كل محتوى الملف و تخزينه في المصفوفة infile.read (memblock, size); // outfile في الملف الجديد الذي يمثله الكائن memblock هنا قمنا بكتابة كل محتوى المصفوفة outfile.write(memblock, size); // لإغلاق الإتصال مع الملفات المفتوحة في الذاكرة outfile و infile من الكائنين close() هنا قمنا باستدعاء الدالة infile.close(); outfile.close(); } else { // إذا حدث أي مشكلة أثناء فتح الملف الأول أو إنشاء و فتح الملف الثاني سيتم طباعة هذه الجملة cout << "Operation failed!"; } return 0; }
•عند تشغيل البرنامج, سيتم إنشاء نسخة من الملف إن تحدث أي مشكلة و لن يتم طباعة أي شيء في البرنامج.
•عند تشغيل البرنامج, إذا كان يوجد مشكلة في مسارات الملفات الموضوعة أو أنه لا يمكن إنشاؤه لأي سبب كان سيتم طباعة الجملة التالية.
Operation failed!
كيفية حفظ ما يدخله المستخدم بداخل ملف.
هنا وضعنا مثال حول كيفية حفظ ما يدخله المستخدم بداخل ملف.
في المثال التالي قمنا بإنشاء ملف نصي جديد إسمه data.txt
في نفس المشروع الذي نعمل فيه.
بعدها قمنا بالتأكد من أنه قد تم إنشاء الملف بنجاح.
بعدها طلبنا من المستخدم إدخال إسمه و من ثم قمنا بتخزين الإسم الذي يدخله بداخل الملف data.txt
.
#include <iostream> #include <fstream> using namespace std; int main() { // لأننا سنستخدمه لإنشاء ملف جديد و الكتابة فيه outfile إسمه ofstream هنا قمنا بإنشاء كائن من الكلاس ofstream outfile; // لتخزين الإسم الذي سيدخله المستخدم عند التشغيل name قمنا بتجهيز المتغير string name; // و فتحه "data.txt" لإنشاء ملف جديد إسمه open() هنا قمنا باستدعاء الدالة outfile.open("data.txt"); // لا يوجد فيه أي مشاكل قبل التعامل معه outfile هنا قمنا بالتأكد من أن الإتصال بالملف الذي يشير له الكائن if(outfile) { // name هنا سيطلب من المستخدم إدخال إسمه الكامل و من ثم سيتم تخزين الإسم الذي يدخله في المتغير cout << "Enter your name: "; getline(cin, name); // outfile هنا قمنا بإضافة نص في الملف الذي يشير إليه الكائن outfile << name; } // لإغلاق الإتصال مع الملف المفتوح في الذاكرة outfile من الكائن close() هنا قمنا باستدعاء الدالة outfile.close(); return 0; }
•قمنا بتعليم البيانات التي إنتظرنا البرنامج لإدخالها من لوحة المفاتيح باللون الأصفر.
•قم بفتح الملف data.txt
الذي تم إنشاؤه في نفس المشروع الذي تعمل فيه و ستجد أنه قد تم حفظ ما أدخلته فيه.
.....................................................................