2010-10-19 3 views
6

Я анализирую файл с данными MalFormed время от времени.Eating Exceptions

и ы бросать исключение,

я хотел бы восстановиться после исключения и игнорировать плохие отформатированные данные.

Каков наилучший способ для этого?

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

* EDIT: * Я думаю, что мой вопрос не был хорошо понимал. Я хотел бы восстановить из исключения, любое исключение в этом отношении, я не хочу, чтобы моя программа остановилась. но продолжать.

+11

Ловля общего исключения - плохая идея. Вы должны улавливать только те исключения, с которыми вы можете справиться. Это неоднократно возникало при переполнении стека. – ChrisF

+0

Вы хотите игнорировать все данные текущего анализа или просто строки/элементы/символы, которые являются плохими? – hemp

+4

И здесь я думал, что это будет о том, чтобы отклониться от китайской пищи от обычной пиццы пепперони. (Неужели плохо, когда ребята, которые отвечают за доставку, знают ваше имя, что вы делаете и немного о проектах, над которыми работаете?) – Brad

ответ

5

Я думаю, что вы спрашиваете, это:

При разборе файла построчно, иногда текущая строка имеет неверные данные, которые вызывает исключение в код. Возможно, вам просто нужно структурировать свой код таким образом, чтобы try/catch окружал только синтаксический код, а не код чтения строки. Например:

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

Внешняя попытка/поймать блок для обработки закрытия объекта чтения должным образом, если что-то произошло при попытке открыть или прочитать файл. Внутренний блок try/catch состоит в проглатывании исключений, возникающих, если считываемые данные искажены и не могут быть правильно проанализированы.

Я согласен с почти всем остальным. Просто глотать исключение может быть не очень хорошо. По крайней мере, я рекомендую вам зарегистрировать его где-нибудь.

+1

Во внешнем улове вы захотите использовать 'throw;' вместо того, чтобы обернуть исходное Исключение в новом, чтобы сохранить стек вызовов. Кроме того, если вы используете 'using (reader = new StreamReader (путь к файлу)), тогда вам не нужен этот внешний блок исключений. – hemp

+0

@hemp Стоит упомянуть, что 'throw;' не всегда будет сохранять стек вызовов и 'throw ex'', тем более. Смотрите: https://weblogs.asp.net/fmarguerie/rethrowing-exceptions-and-preserving-the-full-call-stack-trace – Dan

+0

Вы правы @ Dan, в случае, когда исключение бросается, поймано, и возвращенный в ту же функцию, трассировка стека будет показывать только информацию о том, где она была восстановлена. На практике это редкий случай. – 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

Это работает - может быть, вы могли бы войти ошибки, хотя тоже в случае, если вы хотели посмотреть, что данные, что вызвало исключение произойдет и использовать, чтобы улучшить вашу логику синтаксического анализа.

4

Короче говоря, вы, вероятно, не должны использовать исключения для этого. Что-то вроде TryParse, который возвращает false, намного эффективнее и легче восстанавливается. Обработка исключений - это немного тупой подход.

MSDN Guidance on Exception Handling

+2

TryParse применим только в том случае, если вы читаете некоторые примитивные типы, которые предоставляют методы TryParse. «TryParse» без исключений невозможен, если вы разбираетесь в файловом потоке и этот файл отсутствует - вам понадобится обработка исключений * где-нибудь * для обработки исключения FileNotFoundException. –

+0

@ Джейсон, я думаю, ты собираешь гниды. Метод TryParse доступен в любое время, когда вы его пишете. Если вы никогда его не писали, вы, вероятно, ошибаетесь. MSDN называет его шаблоном [«Tester-Doer»] (http://msdn.microsoft.com/en-us/library/ms229009.aspx) и поощряет его как предпочтительную практику (над обработкой исключений). Не открывайте файл для его анализа; вместо этого сначала проверьте, существует ли он, затем попытайтесь открыть его для чтения, а затем попытайтесь разобрать открытый поток. Если вы следуете этому шаблону, не требуется FileNotFoundException, если вы не решите его выбросить. – hemp

+1

@hemp: Если вы проверяете, существует ли файл, попробуйте открыть его для чтения, вы получите исключение FileNotFound, когда другой поток или другой процесс удалит файл между вашим вызовом IsExists() и фактически откроет файл. Как бы редко это ни было, ваш код ошибочен, если вы не имеете дело с возможным исключением. Проблема в том, что вы * не можете * всегда избегать обработки исключений (насколько мне бы хотелось). Да, вы можете написать метод TryParse, но, чтобы написать его правильно, вам почти наверняка придется включить в него обработку исключений - вы просто перемещаете сайт catch {}. –

2

Существует несколько хороших фон информация здесь: Is there any valid reason to ever ignore a caught exception

Короткий ответ: исключения являются дорогостоящими, чтобы использовать таким образом. Если это вообще возможно, протестируйте входные данные перед отправкой их для обработки и игнорируйте их, а не игнорируйте исключения.

Также убедитесь, что вы не используете слишком широкую сеть и не имеете законных исключений, о которых вы, возможно, захотите узнать.

3

В общем, что-то вроде этого:

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

Вы должны избегать ловель общих Exception дел и вместо того, чтобы поймать конкретное исключение, что бы это ни было.

1

Поймать общее исключение - плохая идея, если вы ожидаете, что он будет генерировать только один или два конкретных типа исключения для ошибок, связанных с синтаксическим разбором. Обычно лучше поймать каждый конкретный тип исключения и обрабатывать его независимо, чтобы ваш код не подавлял какую-либо другую (возможно, непредвиденную) ошибку (например, если файл отсутствует или время подключения к сети, следует ли его обрабатывать в точно так же, как если бы файл содержал поврежденные данные?)

Однако уловка общего исключения - отличная идея, если вы намеренно нуждаетесь/хотите поймать все возможные ошибки и изящно продолжать. Это может произойти, если обработка всех типов ошибок одинакова (например, «если по какой-либо причине я не могу прочитать это значение предпочтения, я верну его значение по умолчанию 5» - это бесконечно лучше, чем сбой вашей программы, потому что вы не " t понимают, что это может вызвать исключение из-за сетевого таймаута). Если использовать разумно, этот подход может сделать вашу программу пуленепробиваемой, но если ее использовать неразумно, вы можете подавить ошибки, о которых вам нужно знать и исправить, и это может быть очень болезненным.

При подавлении любых исключений вы всегда должны внимательно относиться к сообщениям об ошибках - должны ли вы сообщить пользователю, что у вас возникла проблема? Если вы зарегистрируете его в файле трассировки, чтобы, когда клиент жалуется на что-то, что не работает правильно, вы можете вернуться к источнику проблемы? Или вы должны молча игнорировать его?Просто будьте осторожны, так как чрезмерно усердные подавления могут затруднить работу прогамы, которая непредсказуемо ведет себя.

0

У меня возникает ощущение, что вы видите такие вещи, как черный & белый, и это не очень хорошо .. Да, в большинстве случаев нехорошо поймать все и быть неряшливым, когда дело доходит до проверки ввода, но не всегда. Это может быть особый случай. Я ничего не знаю о том, какие файлы будут разбираться, но исключения могут быть правильными.

Перед тем, как решить, что лучше, дайте нам более подробно :)