You are on page 1of 6

‫جامعة ادلب‬

‫كلية الهندسة المعلوماتية‬


‫السنة الثانية ‪ -‬مادة برمجة متقدمة ‪1‬‬

‫الفصل الثاني‬

‫الملفات النصية في لغة سي شارب‬


‫يمكن القراءة والكتابة من وإلى الملفات النصيّة في سي شارب بعدّة طرق‪ .‬سنتناول أسلوبًا بسي ً‬
‫طا وذلك من‬
‫خالل الصنفين ‪StreamWriter‬و ‪.StreamReader.‬‬
‫سمح الصنف ‪ StreamWriter‬بالكتابة فقط‪ ،‬أ ّما الصنف ‪ StreamReader‬فهو يسمح بالقراءة‬
‫فقط‪ .‬كما يمكن استخدام كال الصنفين في نفس البرنامج‪ .‬وك ّل منهما موجود ضمن نطاق‬
‫االسم ‪.System.IO.‬‬
‫يرث‬ ‫حين‬ ‫في‬ ‫يرث الصنف ‪ StreamWriter‬من الصنف ‪TextWriter‬‬
‫الصنف ‪ StreamReader‬من الصنف ‪. TextReader.‬‬

‫الكتابة إلى الملف النصي‪:‬‬


‫سنعمل في البرنامج التالي على انشاء الملف ‪ data.text‬وكتابة بعض األسطر ضمنه ‪:‬‬
‫)‪static void Main(string[] args‬‬
‫{‬
‫‪string[] lines = { "first line", "second line" ,"third‬‬
‫;}"‪line‬‬
‫;)"‪StreamWriter filewriter= new StreamWriter(@"d:\\data.txt‬‬
‫)‪foreach (string line in lines‬‬
‫{‬
‫;)‪filewriter.WriteLine(line‬‬
‫}‬
‫;)(‪filewriter.Close‬‬
‫}‬
‫شرح البرنامج ‪:‬‬
‫صرحنا عن المصفوفة ‪ lines‬التي عناصرها نصوص‪ ،‬الحظ أنّنا استخدمنا الطريقة المختصرة إلنشاء‬ ‫ّ‬
‫كائن مصفوفة وإسناد العناصر الموجودة ضمن الحاضنة { } إلى عناصره مباشرة ً‪.‬‬
‫نصرح عن المتغيّر ‪ fileWriter‬حيث نسند إليه كائن من الصنف ‪ StreamWriter.‬عند‬ ‫ّ‬
‫مع تحديد المسار إلى بانية الصنف‬ ‫مررنا اسم الملف "‪"data.txt‬‬ ‫إنشاء هذا الكائن‪ّ ،‬‬
‫‪ StreamWriter.‬في الحقيقة تخضع هذه البانية إلى زيادة التحميل ‪ ، overloading‬حيث لها‬

‫‪1‬‬ ‫م‪.‬بسمة سراقبي‬


‫جامعة ادلب‬
‫كلية الهندسة المعلوماتية‬
‫السنة الثانية ‪ -‬مادة برمجة متقدمة ‪1‬‬

‫ثمانية أشكال مختلفة اخترنا أبسطها‪ ،‬وهو مسار واسم الملف المراد إنشاؤه‪ .‬وبما أنّنا ّ‬
‫مررنا االسم مع المسار‪،‬‬
‫فسيتم إنشاء هذا الملف في نفس المسار المحدد ‪.‬‬
‫بعد ذلك نستخدم التابع ‪ WriteLine‬من المتغيّر ‪ fileWriter‬لكتابة عناصر‬
‫المصفوفة ‪lines‬على أسطر منفصلة ضمن الملف ‪ data.txt.‬العبارة البرمجيّة في السطر‬
‫األخير ضرورية إلغالق الملف باستدعاء التابع ‪ Close‬وتحرير المصدر الذي يحجزه في نظام التشغيل‪.‬‬
‫جرب تنفيذ البرنامج‪ ،‬لن تحصل على شيء على الشاشة‪ ،‬ولكن إذا فتحت الملف ‪ data.txt‬تجد ضمنه‬ ‫ّ‬
‫ّ‬
‫مجلد المشروع )ستجد األسطر الثالثة موجودة ً ضمنه)‪.‬‬
‫مالحظة مهمة في التعامل مع الملفات ‪:‬‬
‫عند انشاء كائن للقراءة من الملف أصبح الملف مشغوالً من قبل البرنامج الخاص بك ‪ ,‬حيث قمت بفتح‬
‫مجرى مع الملف للتعامل معه ‪ ,‬فيجب علينا بعد تنفيذ العمليات على الملف سواء القراءة منه أو الكتابة فيه‬
‫اغالق ذلك المجرى ويكون عبر استخدام الدالة ;)(‪. close‬‬
‫أن مصادر نظام‬ ‫في الحقيقة ليس هذا هو االستخدام األمثل للصنف ‪ StreamWriter‬والسبب في ذلك ّ‬
‫التشغيل محدودة‪ ،‬حيث يؤدّي التعامل مع الملفات إلى حجز بعض من هذه المصادر‪ ،‬لذلك ينبغي تحرير هذه‬
‫فورا عندما تنتهي الحاجة إليها‪ .‬قد يبدو أنّنا قد فعلنا ذلك باستخدام التابع ‪ Close‬وهذا صحيح‬
‫المصادر ً‬
‫تما ًما‪ ،‬ولكن ليس بالسرعة القصوى الممكنة! هناك أسلوب آخر يسمح بتحرير المصادر بشكل أكثر فعاليّة‬
‫وسرعة باستخدام الكلمة المحجوزة ‪using.‬سأعدّل البرنامج السابق ليستخدم هذا األسلوب الجديد‪ .‬انظر‬
‫البرنامج بعد التعديل‪:‬‬
‫)‪static void Main(string[] args‬‬
‫{‬
‫" ‪string[] lines = { "c# programming", " c programming‬‬
‫;}" ‪," c++ programming‬‬
‫‪using (StreamWriter filewriter=new‬‬
‫))"‪StreamWriter(@"d:\data.txt‬‬
‫)‪foreach (string line in lines‬‬
‫{‬
‫;)‪filewriter.WriteLine(line‬‬
‫}‬
‫}‬
‫الحظ كيف وضعنا عبارة التصريح عن المتغيّر ‪ fileWriter‬واإلسناد إليه ضمن عبارة ‪using.‬‬
‫وبمجرد وصول تنفيذ‬‫ّ‬ ‫في الواقع لن يكون المتغيّر ‪ fileWriter‬مرئيًّا خارج حاضنة ‪،using‬‬
‫فورا وتحرير المصدر الذي يحجزه‪ .‬يظهر من البرنامج السابق أنّنا‬
‫البرنامج إلى القوس سيتم إغالق الملف ً‬
‫لم نعد نحتاج إلى استخدام التابع ‪. Close.‬‬

‫‪2‬‬ ‫م‪.‬بسمة سراقبي‬


‫جامعة ادلب‬
‫كلية الهندسة المعلوماتية‬
‫السنة الثانية ‪ -‬مادة برمجة متقدمة ‪1‬‬

‫القراءة من الملف النصي‪:‬‬


‫سنستخدم الصنف ‪ StreamReader‬لهذا الغرض‪ .‬سيعمل البرنامج على قراءة محتويات‬
‫الملف ‪ data.txt‬السابق وعرضها على الشاشة‪:‬‬
‫)‪static void Main(string[] args‬‬
‫{‬
‫‪using (StreamReader filereader=new‬‬
‫))"‪StreamReader(@"d:\data.txt‬‬
‫{‬
‫)‪while (!filereader.EndOfStream‬‬
‫{‬
‫;)(‪string line = filereader.ReadLine‬‬
‫;)‪Console.WriteLine(line‬‬
‫}‬
‫}‬
‫;)(‪Console.ReadKey‬‬
‫}‬
‫شكال مختلفًا تسمح‬‫ً‬ ‫ضا لزيادة التحميل‪ ،‬حيث تمتلك ‪11‬‬
‫تخضع بانية الصنف ‪ StreamReader‬أي ً‬
‫للمبرمج بالتح ّكم الكامل بكيفيّة القراءة من الملف‪ .‬أبسط هذه األشكال هو الشكل الذي استخدمناه في‬
‫سنمرر لهذه البانية اسم الملف ‪ data.txt‬الذي أنشأناه في البرنامج في الفقرة‬
‫ّ‬ ‫البرنامج السابق حيث‬
‫ضا العبارة ‪ using‬لتحرير المصدر الذي يحجزه الملف عند‬ ‫السابقة ‪ .‬استخدمنا في هذا البرنامج أي ً‬
‫االنتهاء من القراءة‪ .‬ننشئ كائن من الصنف ‪ StreamReader‬ونسنده إلى المتغيّر‬
‫‪fileReader‬ضمن عبارة ‪ using‬ث ّم نستخدم حلقة ‪ while‬لقراءة محتويات الملف‪ ،‬وذلك ألنّنا‬
‫سطرا يحوي الملف‪ .‬الحظ شرط استمرار حلقة ‪ while‬حيث‬ ‫ً‬ ‫من الناحية النظريّة ال نعلم بالتحديد كم‬
‫تُرجع الخاصيّة ‪ EndOfStream‬للمتغيّر ‪fileReader‬ا لقيمة ‪true‬إذا وصلنا إلى نهاية‬
‫وإال فإنّها تُرجع ‪false.‬إ ًذا‪ ،‬في حال لم نصل بعد إلى نهاية الملف ستُرجع‬
‫الملف أثناء عمليّة القراءة‪ّ ،‬‬
‫الخاصيّة القيمة ‪ EndOfStream‬القيمة ‪false‬وبسبب وجود عامل النفي المنطقي (!) قبل هذه‬
‫الخاصيّة مباشرةً‪ ،‬ستكون القيمة النهائيّة لهذا التعبير هو ‪ true‬مما يسمح لحلقة ‪ while‬باالستمرار‪.‬‬
‫أ ّما عند الوصول إلى نهاية الملف سيحدث العكس تماما ً مما يجعل شرط استمرار الحلقة ‪ false‬وينتهي‬
‫تنفيذ الحلقة‪.‬‬
‫سطرا من الملف ‪ data.txt‬ونسنده إلى المتغيّر النصي ‪line‬في كل دورة‪ ،‬ث ّم نطبع‬ ‫ً‬ ‫ثم نقرأ في‬
‫محتويات هذا المتغيّر إلى الشاشة‪ .‬استخدمنا في عمليّة قراءة سطر من الملف ‪data.txt‬‬
‫التابع ‪ ReadLine‬مع المتغيّر ‪ fileReader‬الذي يعمل على قراءة سطر واحد في ك ّل ّ‬
‫مرة من‬
‫الملف ‪data.txt.‬‬

‫‪3‬‬ ‫م‪.‬بسمة سراقبي‬


‫جامعة ادلب‬
‫كلية الهندسة المعلوماتية‬
1 ‫ مادة برمجة متقدمة‬- ‫السنة الثانية‬

:‫تمرين‬
‫اكتب برنامج بلغة سي شارب يقوم بقراءة ثالث ملفات نصية‬
‫( ودمجها في ملف نصي آخر‬d:\\t1.txt)(d:\\t2.txt)(d:\\t3.txt)
. (c:\\t.txt)
static void Main(string[] args)
{
StreamWriter sw1 = new StreamWriter(@"d:\\t1.txt");
string t1 = " c# programming ";
sw1.WriteLine(t1);
sw1.Close();
StreamWriter sw2 = new StreamWriter(@"d:\\t2.txt");
string t2 = " c programming ";
sw2.WriteLine(t2);
sw2.Close();
StreamWriter sw3 = new StreamWriter(@"d:\\t3.txt");
string t3 = " c++ programming ";
sw3.WriteLine(t3);
sw3.Close();
StreamWriter sw = new StreamWriter(@"d:\\t.txt");
StreamReader sr = new StreamReader(@"d:\\t1.txt");
sw.WriteLine(sr.ReadToEnd());
sr.Close();
sr = new StreamReader(@"d:\\t2.txt");
sw.WriteLine(sr.ReadToEnd());
sr.Close();
sr = new StreamReader(@"d:\\t3.txt");
sw.WriteLine(sr.ReadToEnd());
sr.Close();
sw.Close();
Console.ReadKey();
}

4 ‫بسمة سراقبي‬.‫م‬
‫جامعة ادلب‬
‫كلية الهندسة المعلوماتية‬
‫السنة الثانية ‪ -‬مادة برمجة متقدمة ‪1‬‬

‫تمرين ‪:‬‬
‫اكتب برنامج بلغة ‪ c#‬يقوم بحذف أي سطر يحتوي عددا ً موجبا ً من ملف يتألف من عدة أسطر في كل‬
‫سطر عدد صحيح واحد فقط ‪.‬‬
‫)‪static void Main(string[] args‬‬
‫{‬
‫;)"‪StreamWriter sw = new StreamWriter(@"d:\s.txt‬‬
‫;"‪string s = "5\n4\n2\n-4\n7\n-48‬‬
‫;)‪sw.WriteLine(s‬‬
‫;)(‪sw.Close‬‬
‫;)"‪StreamReader sr = new StreamReader(@"d:\s.txt‬‬
‫;)(‪string line = sr.ReadLine‬‬
‫;"" = ‪string nexttext‬‬
‫)‪while (line != null‬‬
‫{‬
‫)‪if (Convert.ToInt32(line) < 0‬‬
‫{‬
‫;"‪nexttext += line + "\n‬‬
‫}‬
‫;)(‪line = sr.ReadLine‬‬
‫}‬
‫;)(‪sr.Close‬‬
‫;)‪File.WriteAllText(@"d:\\s.txt", nexttext‬‬
‫;)(‪Console.ReadKey‬‬
‫}‬
‫سوف نقوم بدايةً بقراءة سطر سطر من الملف وفي كل سطر سنقوم بتحويل القيمة النصيّة إلى عدد صحيح‬
‫ونختبره في حال كان سالب نقوم بتخزينه في متحول نصي ‪ ,‬وفي نهاية قراءة جميع األسطر ‪ ,‬نقوم بكتابة‬
‫المتحول النصي الناتج عن األعداد السلبية داخل المستند النصي مع استبدال النص السابق الذي داخله ‪:‬‬
‫;)"‪StreamReader sr = new StreamReader(@"d:\\s.txt‬‬
‫;)(‪string line = sr.ReadLine‬‬
‫;"" = ‪string nexttext‬‬

‫قمنا بتعريف كائن من الصف الخاص بقراءة الملف ومررنا له مسار الملف ‪ ,‬ثم أنشأنا متحول نصي وخزنا‬
‫بداخله سطر من الملف الموجود لدينا ‪ ,‬ومتحول نصي آخر سنقوم بتخزين األعداد السالبة الموجودة في‬
‫النص بداخله ‪.‬‬

‫‪5‬‬ ‫م‪.‬بسمة سراقبي‬


‫جامعة ادلب‬
‫كلية الهندسة المعلوماتية‬
‫السنة الثانية ‪ -‬مادة برمجة متقدمة ‪1‬‬
‫)‪while (line != null‬‬
‫{‬
‫)‪if (Convert.ToInt32(line) < 0‬‬
‫{‬
‫;"‪nexttext += line + "\n‬‬
‫}‬
‫;)(‪line = sr.ReadLine‬‬
‫}‬

‫واآلن قمنا بإنشاء حلقة تكرارية تختبر اذا كان السطر فارغا ً (أي أننا لم نصل لنهاية الملف)ندخل إلى‬
‫الحلقة ونختبر اذا كان السطر يحتوي قيمة عددية أصغر من الصفر نقوم بوضعها في المتحول النصي‬
‫الذي أنشأناه سابقا ً ‪ ,‬وبعدها ننتقل إلى سطر آخر ونعود لنكرر الحلقة لحين تنتهي ‪.‬‬
‫;)(‪sr.Close‬‬
‫;)‪File.WriteAllText(@"d:\\s.txt", nexttext‬‬

‫وفي النهاية اغلقنا الملف الخاص بالقراءة ‪ ,‬واستخدمنا صف جديد باسم ‪ File‬يحتوي على ميثود باسم‬
‫‪ WriteAllText‬تستقبل برامترين ‪ :‬األول هو مسار الملف والثاني هو الملف الذي نريد وضعه في‬
‫الملف المحدد بالمسار ‪.‬‬
‫تقوم هذه الدالة باستبدال النص الموجود في الملف المحدد بالنص المرسل ‪.‬‬

‫‪6‬‬ ‫م‪.‬بسمة سراقبي‬

You might also like