Есть ли надежный способ распознавания исключений ввода-вывода, вызванных заблокированными файлами, кроме анализа атрибута .message? - PullRequest
3 голосов
/ 09 февраля 2010

В качестве примера, предположим следующий фрагмент кода VB.NET для удаления каталога.

 Try
      Dim SomeFolder="c:\somefolder"
      System.IO.Directory.Delete(SomeFolder, True)    
 Catch ioex As System.IO.IOException     
     'What went wrong? 
     'File locked by another process? 
     'File not found? 
     'something else?
 End Try       

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

Проблема состоит в том, что IOException может быть выброшено по любому числу причин, например, неверный путь или флаг только для чтения, установленный в файле. Каждое из этих условий устанавливает различное значение в атрибуте. message объекта исключения, но просто неправильно вводить проверку конкретной строки в сообщении об ошибке, чтобы обнаружить конкретную причину провал. У меня нет большой уверенности, что строки ошибок будут последовательно сформулированы в будущих версиях .net, и я не хотел бы возиться с написанием кода локализации, чтобы иметь дело с возможностью того, что сообщение будет возвращено не на английском .

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

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

Ответы [ 2 ]

7 голосов
/ 09 февраля 2010

Вы можете перехватить некоторые исключения, которые наследуются от IOException .

К ним относятся DirectoryNotFoundException, FileNotFoundException и др.

Используйте Обработка исключений для этого:

Try
  Dim SomeFolder="c:\somefolder"
  System.IO.Directory.Delete(SomeFolder, True)    
Catch fnfex As System.IO.FileNotFoundException     
 'What went wrong? 
 'File not found? 
Catch ioex As System.IO.IOException     
 'What went wrong? 
 'something else?
End Try       

Обновление

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

Dim SomeFolder="c:\somefolder"

If Directory.Exists(SomeFolder) Then
   System.IO.Directory.Delete(SomeFolder, True)
End If

Обновление 2 :

После комментариев и обновления к вопросу о заблокированных файлах. У меня возникла та же проблема, и я прибег к разбору сообщения об исключении, поскольку нет FileLockedException или аналогичного: (

2 голосов
/ 09 февраля 2010

Лучшим вариантом будет сделать ваши проверки заранее, а не полагаться на исключения. Например:

if (Directory.Exists(SomeFolder))
{
    Directory.Delete(SomeFolder, true);
}

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

Редактировать: Не говоря уже о том, что моя опция устраняет необходимость обработки исключений, просто делает их истинными исключениями, а не просто частью обычного потока программы.

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

if (object != null)
{
    object.Value = true;
}

лучше, чем огромный перегруженный catch (пример упрощен):

try
{
    object.Value = true;
}
catch NullRefrenceException
{
    ...
}
catch Exception
{
    ...
}

Редактировать: Относительно обновления ОП о блокировках файлов. Я не верю, что здесь есть более конкретное ожидание, так что разбор сообщения - это, вероятно, ваш единственный вариант. Если вы не можете найти способ проверить блокировку на передней панели без исключения. Даже в этом случае состояние блокировки может измениться между проверкой и попыткой доступа.

...