С# -Почему System.IO.File.GetLastAccessTime возвращает ожидаемое значение, когда файл не найден?
Пожалуйста, объясните свои мысли.
1. DateTime dt = System.IO.File.GetLastAccessTime("C:\\There_is_no_such_file.txt");
2. DateTime dt = System.IO.File.GetLastAccessTime("");
-
Если файл, описанный в параметре пути, не существует, этот метод возвращает 12:00 полночь, 1 января, 1601 г. н.э. (CE) Скоординированное универсальное время (UTC), скорректированное на местное время.
-
Во второй ситуации генерируется аргумент exception.
Почему в первом случае FileNotFoundException (или smth. simmilar) не выбрасывается?
Ответы
Ответ 1
Это документированное поведение. В разделе "Примечания" в разделе "Библиотека MSDN":
Если файл, описанный в параметре пути, не существует, этот метод возвращает 12:00 в полночь, 1 января, 1601 г. A.D. (C.E.) Скоординированное универсальное время (UTC) с поправкой на местное время.
Исключением, которое вы получаете при передаче пустой строки, является то, которое генерируется кодом, который проверяет, является ли переданная строка допустимым именем пути. Что справедливо, это будет ошибкой в программе.
Код явно, поэтому он не был сделан путем надзора или по ошибке. Он использует функцию API FindFirstFile() для поиска файла. Если это не удается, он проверяет ошибку Windows. И явно игнорирует ошибки "Файл не найден", "Путь не найден" и "Жесткий диск".
Остерегайтесь, что предлагаемые решения, использующие File.Exists, на самом деле не предотвращают эту проблему. Windows - многозадачная операционная система. Ваш поток может быть предварительно упущен сразу после вызова Exists, а другой процесс может удалить файл. Когда ваш поток восстановит CPU, вы все равно получите фиктивную дату.
Единственный гарантированный способ получить точную дату - сначала открыть файл, чтобы никто не мог удалить файл из-под вас. Который, я думаю, объясняет, почему метод ведет себя так, как он. Дизайнеры каркаса застряли между скалой и твердым местом. Если бы они сначала открыли файл, они бы рискнули применить другие программы к ошибке обмена файлами. Если они не открывают файл первым, они рискуют вашей программой бомбить случайным образом и нечасто. Чрезвычайно трудно диагностировать. Чтобы выбрать между двумя неприятными вариантами, они выбрали тот, который ничего не бомбит.
Anyhoo, сделайте его надежным, открыв файл.
Ответ 2
Мы имеем дело с двумя разными вещами.
Когда вы вызываете метод с недопустимым аргументом, он должен вызывать исключение.
Если файл не существует, это не обязательно исключение. Поэтому возвращается значение по умолчанию, которое вы можете проверить и решить, как действовать. Для метода GetLastAccessTime не имеет значения, существует ли файл. Если это важно для ВАШЕГО кода, тогда вы должны нести ответственность за генерирование ошибки...
if (!File.Exists("C:\\There_is_no_such_file.txt")) {
throw new FileNotFoundException();
}
Ответ 3
Ну, я не писал ни одной библиотеки System.IO
, поэтому я не могу утверждать, что у меня есть ответ на то, какие исключения бросаются в какой момент. То, что квалифицируется как исключение, всегда будет решением для разработчика.
Я могу взять удар по рассуждениям, стоящим за этим.
Наличие файла, который не существует, может во многих случаях ожидать поведения. Чтобы попасть в файловую систему только для того, чтобы запросить, существует ли файл, а затем ударить его снова, чтобы получить время доступа к этому файлу, может показаться, что это просто накладные расходы, по сравнению с просто удалением файловой системы и проверкой результата. Если DateTime
имеет значение NULL, это, вероятно, дало бы null
, как можно представить, что IndexOf
имел бы вместо -1
.
Во втором случае, однако, передача недопустимого пути является доказательством того, что где-то в вашем коде есть что-то, что ожидает ожидание чего-то, что не может работать, и, возможно, имеет смысл довести это до внимания разработчика, путем исключения исключений.
Ответ 4
Если вы зададите вопрос "Когда был последний раз, был ли доступен файл" There_is_no_such_file.txt "?", вы можете либо ответить "Нет такого файла", либо "никогда".
Очевидно, что команда, которая разработала библиотеку IO, выбрала второй ответ, никогда не представляемый как DateTime.MinValue
.
Ответ 5
Я считаю его дизайном
12:00 midnight, January 1, 1601 A.D. (C.E.) - значение даты minium, некоторые считают это как значение no, но это было после типов с нулевым значением
Ответ 6
Возможно, причина в том, что вы отключили параметр "Включить неуправляемый отладочный код", чтобы проверить свойства проекта в разделе "Отладка".