Frage

Oft finde ich mich mit Dateien in irgendeiner Weise interagieren, aber nach dem Schreiben von Code Ich bin immer unsicher, wie rubust es tatsächlich ist. Das Problem ist, dass ich nicht ganz sicher bin, wie Datei bezogene Operationen fehlschlagen kann und daher der beste Weg, expections zu behandeln.

Die einfache Lösung scheint einfach zu sein, alle IOExceptions durch den Code geworfen zu fangen und dem Benutzer eine „unzugängliche Datei“ Fehlermeldung zu geben, aber ist es möglich, etwas feinkörnige Fehlermeldungen zu erhalten. Gibt es eine Möglichkeit, den Unterschied zwischen einem solchen Fehler zu bestimmen, wie eine Datei von einem anderen Programm gesperrt werden und die Daten unlesbar zu sein aufgrund eines Hardware-Fehler?

das folgende C # -Code gegeben, wie Sie Fehler in einem benutzerfreundlichen behandeln würde (so informativ wie möglich) Art und Weise?

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();
   }
}
War es hilfreich?

Lösung

  

... aber ist es möglich, etwas feinkörnige Fehlermeldungen zu erhalten.

Ja. Gehen Sie weiter und fangen IOException, und verwenden Sie die Exception.ToString() Methode eine relativ entsprechende Fehlermeldung erhalten angezeigt werden soll. Beachten Sie, dass die Ausnahmen von dem .NET Framework erzeugt werden diese nützlichen Saiten liefern, aber wenn Sie vorhaben, Ihre eigene Ausnahme zu werfen, müssen Sie in dieser Zeichenfolge in die Exception Konstruktor, wie Stecker vergessen:

throw new FileNotFoundException("File not found");

Auch absolut, wie pro Scott Dorman , verwenden Sie diese using Aussage. Das, was zu beachten ist allerdings, dass die using Aussage eigentlich nichts catch, die die Art und Weise ist es sein sollte. Ihr Test, um zu sehen, ob die Datei vorhanden ist, zum Beispiel, wird eine Race-Bedingung einführen, das eher sein kann vexing . Es ist nicht tun Sie wirklich etwas Gutes es dort zu haben. So, jetzt, für den Leser haben wir:

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

Kurz gesagt, für grundlegende Dateioperationen:
1. Verwenden Sie using
2 Wickeln Sie die Anweisung using oder Funktion in einem try / catch dass catches IOException
3. Verwenden Sie Exception.ToString() in Ihrem catch eine nützliche Fehlermeldung erhalten
4. Versuchen Sie nicht, selbst außergewöhnliche Probleme mit Dateien zu erkennen. Lassen Sie .NET für Sie das Werfen tun.

Andere Tipps

Das erste, was Sie sollten, sind Ihre Anrufe zu Stream und Stream ändern, um sie in einer using-Anweisung zu wickeln, wie folgt aus:

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

Dies wird kümmern Schließen aufrufen und für Sie entsorgen und wird es tatsächlich in einem Versuch wickeln / finally-Block, so dass die tatsächlichen kompilierten Code sieht wie folgt aus:

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();
}

Der Vorteil hierbei ist, dass Sie der Stream geschlossen sicherzustellen, wird selbst dann, wenn eine Ausnahme auftritt.

Soweit mehr explizite Ausnahmebehandlung, es hängt wirklich davon ab, was Sie wollen passieren. In Ihrem Beispiel explizit testen, ob die Datei vorhanden ist und eine FileNotFoundException werfen, die für die Benutzer genug sein können, aber kann es nicht.

  • Überspringen Sie die File.Exists (); entweder handhabt es an anderer Stelle oder lassen Create () / Opentext () es erhöhen.
  • Der Endbenutzer in der Regel kümmert sich nur, wenn es erfolgreich ist oder nicht. Schlägt dies fehl, nur so sagen, er möchte keine Einzelheiten.

Ich habe keine integrierte Möglichkeit, Details zu was und warum etwas versagt in .NET, fand aber, wenn Sie mit Create nativen gehen Sie Tausende von Fehler-Codes, die Sie, was falsch gelaufen berichten.

Ich sehe den Punkt nicht auf der Existenz einer Datei bei der Prüfung und eine FileNotFoundException ohne Nachricht zu werfen. Der Rahmen wird die FileNotFoundException selbst, mit einer Botschaft werfen.

Ein weiteres Problem bei Ihrem Beispiel ist, dass Sie die try / finally Muster oder die Anweisung using verwenden sollten Ihre Wegwerf-Klassen, um sicherzustellen, richtig selbst angeordnet sind, wenn es eine Ausnahme ist.

Ich möchte folgende diese etwas tun, jede Ausnahme außerhalb des Verfahrens fangen, und die Nachricht der Ausnahme angezeigt werden:

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;
}

würde ich die Anweisung using verwenden Schließen der Datei zu vereinfachen. Siehe MSDN die C # using-Anweisung

Von 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);
     }
  }
scroll top