كيفية التعامل بشكل صحيح استثناءات عند تنفيذ الملف io

StackOverflow https://stackoverflow.com/questions/86766

سؤال

في كثير من الأحيان أجد نفسي التفاعل مع الملفات في بعض الطريق ولكن بعد كتابة التعليمات البرمجية أنا دائما غير مؤكد كيف rubust هو عليه في الواقع.المشكلة هي أنني لست متأكدا تماما كيف ملف العمليات ذات الصلة يمكن أن تفشل ، وبالتالي ، فإن أفضل طريقة للتعامل مع expections.

الحل بسيط يبدو فقط للقبض على أي IOExceptions القيت من قبل رمز تعطي المستخدم "لا يمكن الوصول إليها الملف" رسالة خطأ ولكن هل من الممكن الحصول على أكثر قليلا غرامة الحبيبات رسائل الخطأ.هل هناك طريقة لتحديد الفرق بين مثل هذه الأخطاء كملف حبسهم من قبل برنامج آخر و البيانات غير قابلة للقراءة بسبب الأجهزة الخطأ ؟

نظرا التالية التعليمات البرمجية C#, كيف يمكنك التعامل مع الأخطاء في الاستعمال (مفيدة قدر الإمكان) الطريقة ؟

public class IO
{
   public List<string> ReadFile(string path)
   {
      FileInfo file = new FileInfo(path);

      if (!file.Exists)
      {
         throw new FileNotFoundException();
      }

      StreamReader reader = file.OpenText();
      List<string> text = new List<string>();

      while (!reader.EndOfStream)
      {
         text.Add(reader.ReadLine());
      }

      reader.Close();
      reader.Dispose();
      return text;
   }

   public void WriteFile(List<string> text, string path)
   {
      FileInfo file = new FileInfo(path);

      if (!file.Exists)
      {
         throw new FileNotFoundException();
      }

      StreamWriter writer = file.CreateText();

      foreach(string line in text)
      {
         writer.WriteLine(line);
      }

      writer.Flush();
      writer.Close();
      writer.Dispose();
   }
}
هل كانت مفيدة؟

المحلول

لكن هل من الممكن الحصول على أكثر قليلا غرامة الحبيبات رسائل الخطأ.

نعم.والمضي قدما في الصيد IOException, و استخدام Exception.ToString() طريقة الحصول نسبيا ذات الصلة ظهور رسالة خطأ على الشاشة.علما أن الاستثناءات التي تولدها .NET Framework سوف نورد هذه مفيدة سلاسل, ولكن إذا كنت تنوي رمي الخاص بك استثناء ، يجب أن نتذكر أن المكونات في هذه السلسلة في Exception's منشئ, مثل:

throw new FileNotFoundException("File not found");

أيضا, تماما كما في سكوت درمان, استخدم هذا using البيان.الشيء الملاحظ ، على الرغم من أن using بيان الواقع لا catch أي شيء الذي هو الطريقة التي يجب أن يكون.الاختبار الخاصة بك لمعرفة ما إذا كان الملف موجودا ، فعلى سبيل المثال ، سوف أعرض حالة سباق التي قد تكون نوعا ما المحيرة.لا تفعل أي خير لكم أن يكون ذلك في هناك.هكذا, الآن, للقارئ لدينا:

try {  
    using (StreamReader reader = file.OpenText()) {  
        // Your processing code here  
    }  
} catch (IOException e) {  
    UI.AlertUserSomehow(e.ToString());  
}

في عمليات الملفات الأساسية:
1.استخدام using
2 التفاف باستخدام بيان أو وظيفة في try/catch أن catches IOException
3.استخدام Exception.ToString() في catch للحصول على فائدة رسالة الخطأ
4.لا تحاول كشف استثنائية ملف القضايا نفسك.السماح .صافي القيام رمي بالنسبة لك.

نصائح أخرى

أول شيء يجب أن التغيير المكالمات الخاصة بك إلى StreamWriter و StreamReader إلى التفاف عليها في استخدام بيان مثل هذا:

using (StreamReader reader = file.OpenText())
{
   List<string> text = new List<string>();
   while (!reader.EndOfStream)
   {
      text.Add(reader.ReadLine());
   }
}

هذا سوف تأخذ الرعاية من الاتصال الوثيق والتخلص لك و فعلا ألفه في محاولة/أخيرا كتلة لذا الفعلية التعليمات البرمجية المترجمة يبدو مثل هذا:

StreamReader reader = file.OpenText();
try
{
   List<string> text = new List<string>();
   while (!reader.EndOfStream)
   {
      text.Add(reader.ReadLine());
   }
}
finally
{
   if (reader != null)
      ((IDisposable)reader).Dispose();
}

الفائدة هنا هي أن عليك التأكد من تيار يحصل مغلقة حتى في حالة حدوث استثناء.

بقدر أي أكثر وضوحا التعامل مع استثناء, انها حقا يتوقف على ما تريد أن يحدث.في المثال الخاص بك صراحة الاختبار إذا كان الملف موجود و رمي FileNotFoundException والتي قد تكون كافية للمستخدمين ولكن قد لا.

  • تخطي الملف.يوجد();إما التعامل معها في أماكن أخرى أو السماح CreateText()/OpenText() رفعه.
  • المستخدم عادة يهتم فقط إذا نجحت أم لا.إذا فشل أقول ذلك أنه لا يريد التفاصيل.

لم أجد المدمج في طريقة للحصول على تفاصيل حول ماذا ولماذا شيء فشلت في .صافي ، ولكن إذا ذهبت الأم مع CreateFile لديك الآلاف من الخطأ-الرموز التي يمكن أن أقول لكم ما حدث من خطأ.

أنا لا أرى فائدة في التحقق من وجود الملف ورمي FileNotFoundException مع أية رسالة.الإطار رمي FileNotFoundException نفسها ، مع الرسالة.

مشكلة أخرى مع المثال الخاص بك هو أن عليك أن تكون باستخدام حاول/أخيرا نمط أو العبارة باستخدام لضمان المتاح الطبقات يتم التخلص منها بشكل صحيح حتى عندما يكون هناك استثناء.

وأود أن تفعل شيء من هذا القبيل ما يلي التقاط أي استثناء خارج الأسلوب ، وعرض استثناء رسالة :

public IList<string> ReadFile(string path)
{
    List<string> text = new List<string>();
    using(StreamReader reader = new StreamReader(path))
    {
      while (!reader.EndOfStream)      
      {         
         text.Add(reader.ReadLine());      
      }
    }
    return text;
}

أود أن استخدم العبارة باستخدام على تبسيط إغلاق الملف.انظر MSDN C# باستخدام بيان

من MSDN:

  using (TextWriter w = File.CreateText("log.txt")) {
     w.WriteLine("This is line one");
     w.WriteLine("This is line two");
  }
  using (TextReader r = File.OpenText("log.txt")) {
     string s;
     while ((s = r.ReadLine()) != null) {
        Console.WriteLine(s);
     }
  }

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

مبلغ-حتى التي قد تكون المقالة التالية http://goit-postal.blogspot.com/2007/03/brief-introduction-to-exception.html .

وأود أن محاولة التحقق من الملف.موجود قبل استدعاء الخاص بك قراءة/كتابة الرد على المستخدم هناك, بدلا من إنشاء النفقات العامة ورفع خطأ و القبض عليه في وقت لاحق منذ التحقق من السهل جدا لجعل.أنا أفهم الحاجة إلى رفع أخطاء ولكن في هذه وبشكل خاص حالة فحص بسيط imho سيكون أفضل حل.ما أعنيه هو إضافة مزيد من طريقة للتحقق مما إذا كان الملف موجودا.

أيضا إذا كنت لا تحقق مسبقا إذا كان الملف المخارج ، كنت أعرف أن شيئا آخر هو منع ذلك إذا كنت لا يمكن أن يكتب لها.أيضا يمكنك التقاط عدة استثناءات أول مباراة سوف تكون اشتعلت - ولكن ربما كنت أعرف هذا...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top