validar reemplazar mover limpiar fichero eliminar duplicar copia como carpeta archivos archivo c# .net file-io exception-handling

mover - reemplazar archivo c#



Cómo manejar adecuadamente las excepciones cuando se realiza el archivo io (7)

A menudo me encuentro interactuando con archivos de alguna manera, pero después de escribir el código, siempre estoy seguro de qué tan puro es realmente. El problema es que no estoy del todo seguro de cómo pueden fallar las operaciones relacionadas con archivos y, por lo tanto, la mejor manera de manejar las expectativas.

La solución simple parecería ser simplemente capturar cualquier IOExceptions lanzada por el código y darle al usuario un mensaje de error "Inaccesible file" pero es posible obtener un poco más de mensajes de error de grano fino. ¿Hay alguna manera de determinar la diferencia entre tales errores como un archivo bloqueado por otro programa y los datos son ilegibles debido a un error de hardware?

Dado el siguiente código C #, ¿cómo manejaría los errores de una manera fácil de usar (lo más informativa posible)?

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


Lo primero que debe cambiar son sus llamadas a StreamWriter y StreamReader para envolverlas en una declaración de uso, como esta:

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

Esto se encargará de llamar a Close and Dispose para ti y lo envolverá en un bloque try / finally para que el código compilado real se vea así:

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

El beneficio aquí es que se asegura de que la transmisión se cierre incluso si se produce una excepción.

En cuanto a cualquier manejo de excepciones más explícito, realmente depende de lo que quiere que suceda. En su ejemplo, prueba explícitamente si el archivo existe y lanza una excepción FileNotFoundException que puede ser suficiente para sus usuarios, pero puede que no.


No veo el punto de verificar la existencia de un archivo y lanzar una excepción FileNotFoundException sin mensaje. El marco lanzará FileNotFoundException, con un mensaje.

Otro problema con su ejemplo es que debe utilizar el patrón try / finally o la instrucción de uso para asegurarse de que sus clases desechables se eliminen correctamente incluso cuando exista una excepción.

Haría esto de la siguiente manera, captaría cualquier excepción fuera del método y mostraría el mensaje de la excepción:

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


Quizás esto no es lo que está buscando, pero reconsidere el tipo en que está utilizando el manejo de excepciones. Al principio, el manejo de excepciones no debe tratarse como "amigable para el usuario", al menos mientras piense en un programador como usuario.

Un resumen de esto puede ser el siguiente artículo http://goit-postal.blogspot.com/2007/03/brief-introduction-to-exception.html .


Usaría la instrucción using para simplificar el cierre del archivo. Ver MSDN la declaración usando C #

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


Yo trataría de verificar el archivo. Existió antes de llamar a su lectura / escritura y responder al usuario allí, en lugar de crear la sobrecarga de generar un error y capturarlo más tarde ya que el cheque es tan fácil de hacer. Entiendo la necesidad de generar errores, pero en este caso particular, una simple comprobación sería una mejor solución. Lo que quiero decir es agregar un método más para verificar si el archivo existe.

Además, si comprueba de antemano si el archivo sale, sabe que hay algo más que lo bloquea si no puede escribir en él. También puedes atrapar varias excepciones, la primera que coincida será atrapada, pero probablemente ya lo sepas ...


  • Omita el archivo. Exists (); o manejarlo en otro lugar o dejar que CreateText () / OpenText () lo eleve.
  • Al usuario final generalmente solo le importa si tiene éxito o no. Si falla, solo dígalo, él no quiere detalles.

No he encontrado una forma integrada de obtener detalles sobre qué y por qué algo falló en .NET, pero si te vuelves nativo con CreateFile tienes miles de códigos de error que pueden decirte lo que salió mal.


... pero es posible obtener mensajes de error un poco más detallados.

Sí. Continúe y capture IOException , y use el método Exception.ToString() para obtener un mensaje de error relativamente relevante para mostrar. Tenga en cuenta que las excepciones generadas por .NET Framework proporcionarán estas cadenas útiles, pero si va a lanzar su propia excepción, debe recordar insertar esa cadena en el constructor de Exception , como:

throw new FileNotFoundException("File not found");

Además, absolutamente, según Scott Dorman , usa esa declaración de using . Lo que hay que notar, sin embargo, es que el enunciado de using realidad no catch nada, que es la forma en que debería ser. Su prueba para ver si el archivo existe, por ejemplo, introducirá una condición de carrera que puede ser bastante molesta . En realidad, no hace ningún bien tenerlo allí. Entonces, ahora, para el lector tenemos:

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

En resumen, para operaciones básicas de archivos:
1. Usa using
2, ajusta la declaración o función using en un try / catch que catch es IOException
3. Utilice Exception.ToString() en su catch para obtener un mensaje de error útil
4. No intente detectar problemas de archivos excepcionales usted mismo. Deje que .NET haga el lanzamiento por usted.