2010-10-19 10 views
6

Estoy analizando un archivo que tiene datos MalFormed de vez en cuando.Comiendo excepciones

y que s lanzar una excepción,

i d como para recuperarse de la excepción e ignorar los malos datos formateados.

¿Cuál es la mejor manera de hacerlo?

try{ 
// parse file 
}catch(Exception){ 
//eat it. 
} 

* EDIT: * Creo, mi pregunta no era bien entendido. Me gustaría recuperarme de la excepción, cualquier excepción para ese asunto, no quiero que mi programa se detenga. pero para continuar

+11

Capturar la excepción general es una mala idea. Solo debe detectar las excepciones específicas que puede manejar. Esto se ha planteado muchas veces en Stack Overflow. – ChrisF

+0

¿Desea ignorar todos los datos del análisis actual, o solo las líneas/elementos/caracteres que son malos? – hemp

+4

Y aquí pensé que esto iba a ser sobre desviarse a la comida china de la pizza normal de pepperoni. (¿Es malo cuando los repartidores saben tu nombre, lo que haces y un poco sobre los proyectos en los que estás trabajando?) – Brad

Respuesta

5

creo que lo que está pidiendo es la siguiente:

al analizar un archivo línea por línea, los datos a veces la línea actual formato incorrecto que se ha provoca una excepción en su código. Tal vez simplemente necesite estructurar su código de modo que el try/catch solo rodee el código de análisis, no el código de lectura de línea. Por ejemplo:

using System; 
using System.IO; 
using System.Windows.Forms; 

public void ParseFile(string filepath) 
{ 
    TextReader reader = null; 

    try 
    { 
     reader = new StreamReader(filepath); 

     string line = reader.ReadLine(); 
     while (!string.IsNullOrEmpty(line)) 
     { 
      try 
      { 
       // parse line here; if line is malformed, 
       // general exception will be caught and ignored 
       // and we move on to the next line 
      } 
      catch (Exception) 
      { 
       // recommended to at least log the malformed 
       // line at this point 
      } 

      line = reader.ReadLine(); 
     } 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("Exception when trying to open or parse file", ex); 
    } 
    finally 
    { 
     if (reader != null) 
     { 
      reader.Close(); 
      reader.Dispose(); 
     } 
     reader = null; 
    } 
} 

El bloque try/catch exterior es de manejar cerrar el objeto lector correctamente si algo ocurrió al intentar abrir o leer el archivo. El bloque try/catch interno se traga las excepciones planteadas si los datos de lectura estaban mal formados y no se podían analizar correctamente.

Estoy de acuerdo con casi todos los demás, sin embargo. Solo tragar la excepción podría no ser bueno. Por lo menos, te recomiendo que inicies sesión en algún lugar.

+1

En la captura externa, querrá usar 'throw;' en lugar de envolver la Excepción original en una nueva, para preservar la pila de llamadas. Además, si usa 'using (reader = new StreamReader (filepath))', entonces no necesita ese bloque externo de excepción. – hemp

+0

@hemp Vale la pena mencionar que 'throw;' no siempre conservará la pila de llamadas, y 'throw ex;' aún menos. Consulte: https://weblogs.asp.net/fmarguerie/rethrowing-exceptions-and-preserving-the-full-call-stack-trace – Dan

+0

Tiene razón @Dan, en el caso en que se lanza la excepción, atrapado, y reasignado en la misma función, la traza de la pila solo mostrará información acerca de dónde fue redistribuida. En la práctica, es un caso raro. – hemp

0
try{ 
    // parse file 
    } 
    catch(Exception){ 
    //eat it. 
    } 
    finally 
    { 
     //cleanup must ... release system resources here (e.g. stream.Close() etc) 
     // code here always executes...even if the exception is unhandled 

    } 

// code will resume execution from this point onwards... 
0

que funciona - tal vez usted podría registrar los errores, aunque también en el caso de que quería ver lo que los datos fue que causó la excepción a suceder y usarlo para mejorar su lógica de análisis.

4

En resumen, probablemente no deberías usar excepciones para esto. Algo así como un TryParse que devuelve falso es mucho más eficiente y fácil de recuperar. El manejo de excepciones es un enfoque de objeto poco contundente.

MSDN Guidance on Exception Handling

+2

TryParse solo es relevante si estás leyendo algunos tipos primitivos que proporcionan métodos TryParse. "TryParse" sin excepciones no es posible si está analizando desde una secuencia de archivos y ese archivo falta; necesitará manejo de excepciones * en algún lugar * para manejar la excepción FileNotFoundException. –

+0

@Jason, creo que estás recogiendo liendres. Un método TryParse está disponible en cualquier momento que escriba uno. Si nunca has escrito uno, probablemente lo estés haciendo mal. MSDN lo llama el [patrón "Tester-Doer"] (http://msdn.microsoft.com/en-us/library/ms229009.aspx) y lo alienta como una práctica preferida (sobre el manejo de excepciones). No abra un archivo para analizarlo; en su lugar, primero prueba para ver si existe, luego intenta abrirlo para leer, luego intenta analizar la secuencia abierta. Si sigue ese patrón, no se necesita FileNotFoundException, a menos que decida lanzar uno. – hemp

+1

@hemp: si prueba si existe un archivo, intente abrirlo para leerlo, obtendrá una excepción FileNotFound cuando otro hilo u otro proceso elimine el archivo entre su llamada IsExists() y realmente abra el archivo. No importa cuán raro sea esto, su código es defectuoso a menos que trate con la posible excepción. El problema es que * no * siempre puedes evitar el manejo de excepciones (tanto como me gustaría). Sí, puedes escribir un método TryParse, pero para escribirlo correctamente, seguramente tendrás que incluir un manejo de excepciones dentro: solo estás moviendo el sitio del catch {}. –

2

Hay buena información de fondo aquí: Is there any valid reason to ever ignore a caught exception

Respuesta corta: excepciones son caros de usar de esta manera. Si es posible, pruebe la entrada antes de enviarla para su procesamiento y haga caso omiso de ella en lugar de ignorar las excepciones.

Asegúrate también de que no estás utilizando una red demasiado amplia y comiendo excepciones legítimas que tal vez quieras conocer.

3

En general, algo como esto:

try 
{ 
    // parse file 
} 
catch (FormatException) 
{ 
    // handle the exception 
} 
finally 
{ 
    // this block is always executed 
} 

Debe evitar agarrar la Exception caso general y en lugar de atrapar una excepción específica, sea lo que sea.

1

Capturar una excepción general es una mala idea si espera lanzar solo uno o dos tipos de excepción específicos para errores específicos de análisis. Por lo general, es mejor capturar cada tipo específico de excepción y manejarlo de forma independiente para que su código no suprima ningún otro error (quizás inesperado) (por ejemplo, si falta el archivo o se agota el tiempo de espera de la conexión de red). del mismo modo que si el archivo contiene datos corruptos?)

Sin embargo, capturar una excepción general es una gran idea si usted deliberadamente necesita/desea detectar todos los errores posibles y continuar con gracia. Esto puede suceder si el manejo de todos los tipos de error es el mismo (por ejemplo, "si, por algún motivo, no puedo leer este valor de preferencia, devolveré el valor predeterminado de 5", es infinitamente mejor que el bloqueo de tu programa porque no lo hiciste). t se da cuenta de que podría lanzar una excepción debido a un tiempo de espera de red). Si se usa con prudencia, este enfoque puede hacer que su programa sea a prueba de balas, pero si se usa imprudentemente, puede suprimir los errores que necesita conocer y corregir, y esto puede ser muy doloroso.

Al suprimir cualquier excepción, siempre debe considerar cuidadosamente los informes de errores, ¿debería decirle al usuario que ha tenido un problema? ¿Debería registrarlo en un archivo de rastreo para que cuando un cliente se queja de que algo no funciona bien, pueda rastrear el origen del problema? ¿O deberías ignorarlo silenciosamente?Solo tenga cuidado ya que las supresiones excesivamente celosas pueden hacer que sea muy difícil averiguar por qué un programa se comporta de manera imprevisible.

0

Tengo la sensación de que ves cosas como negro & blanco, y eso no se siente bien ... Sí, la mayoría de las veces, no es bueno captar todo y ser descuidado en lo que respecta a la validación de entrada, pero no siempre. Este podría ser un caso especial. No sé nada sobre qué tipo de archivos se van a analizar, pero las excepciones pueden ser las correctas.

Antes de decidir qué es lo mejor, nos dan más detalles :)

Cuestiones relacionadas