Должен ли мой метод генерировать собственное исключение, или пусть .NET бросает, если файл не существует?
Вот мой код:
public void ReadSomeFile(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException();
var stream = new FileStream(filePath, ....)
.....
}
Должен ли я сам исключить исключение (см. проверку File.Exists
)? FileStream
уже будет бросать FileNotFoundException
, если файл не существует. Что такое хорошая практика программирования здесь? Анализ кода говорит, что мы должны проверить наши параметры. Но если я передаю этот параметр непосредственно другому методу (мой или чужой код), и этот метод будет генерировать исключение, то в чем преимущество проверки аргумента в моем коде?
Ответы
Ответ 1
if (File.Exists(f)) { DoSomething(f) }
(или его отрицание) является анти-паттерном. Файл может быть удален или создан между этими двумя операторами, поэтому нет смысла проверять его существование таким образом.
Кроме того, как указано в комментариях, в то время как File.Exists()
может возвращать true, фактическое открытие файла может по-прежнему сбой по разным причинам. Поэтому вам придется повторить проверку ошибок и бросить вокруг открытия файла.
Как вы не хотите повторять себя, но вместо этого сохраняйте свой код DRY, просто попробуйте открыть файл и пусть new FileStream()
throw. Затем вы можете поймать исключение, и, если хотите, повторно выбросить оригинал или выбросить исключение, зависящее от приложения.
Конечно, вызов File.Exists()
может быть оправдан, но не в этом шаблоне.
Ответ 2
Ваш метод называется ReadSomeFile
и принимает filename
в качестве его ввода, поэтому для него разумно выбрасывать FileNotFoundException
. Поскольку вы не можете добавить какое-либо значение, поймав исключение, а затем выбросьте его самостоятельно, просто позвольте .NET выбросить его.
Однако, если ваш метод был LoadData(databaseName)
, и ему нужно получить доступ ко многим файлам, перехватить исключение и выбросить настраиваемое исключение, может быть полезно, поскольку вы можете добавить databaseName
к исключению вместе с другой полезной информацией.
Ответ 3
Помимо уже полученных ответов, вы также можете сказать, что это зависит от того, что вы ожидаете.
Если вы хотите прочитать файл журнала, и он не существует, вы хотите выбросить ошибку или просто пустой String (или пустой массив String)?
Если вы возвращаете значение по умолчанию (например, пустую строку), я бы просто обернул содержимое функции в try-catch
(но только ожидаемые ошибки) и вернул значение по умолчанию в блок catch
, возвращая фактическое содержимого в блоке try
.
Это оставило бы три возможные ситуации:
- Возвращается содержимое файла;
- Возвращается значение по умолчанию, поскольку произошла ожидаемая ошибка;
- Ошибка вызывается .NET, потому что вы не заметили эту ошибку.
Ответ 4
Позвольте правильному методу попытаться открыть файл, пока вы не имеете представления о полном
имя файла, что-то вроде специальных имен файлов (например, Файлы устройств и UNC-пути):
В некоторых случаях другие методы файлов могут быть неудачными, но открытие файла успешно.
Некоторые примеры для специальных имен файлов:
- CON
- NUL
- COM1, COM2, COM3, COM4
- \\сервер\папка\file_path
- \\teela\admin $\ system32 (для доступа к C:\WINNT\system32)
- C:..\File.txt
- \\.\COM1
- % TEMP%
- и многое другое...