Вопрос по c#, asp.net – Как определить причину исключения System.IO.IOException по существующему файлу?

5

Я хочу создать и открыть файл, но только если он не существует. Я не хочу использовать File.Exists, потому что поток за переключателем создает файл с тем же именем.

Как проверить, было ли исключение System.IO.IOException вызвано существующим файлом? Я предпочитаю не анализировать сообщение об ошибке (даже если это может быть так просто, как .indexOf (& quot; Существовать & quot;))

Как мне это сделать?

DevelopingChris: нет, я просто не хочу случайно перезаписывать его, так как есть шанс, что мой генератор randomId (использующий класс random) может генерировать идентичные идентификаторы из-за многоядерности и синхронизации user34537
это файл семафор, почему так много споров? DevelopingChris
Смотрите такжеstackoverflow.com/questions/425956/…, Принятый ответ имеет очень полезную ссылку. finnw

Ваш Ответ

5   ответов
3

Вы всегда можете проверить File.Exists () ... в WITHIN блоке исключений. Вы не хотите проверять ранее из-за многопоточности, поэтому проверьте после того, как вы уже знаете, что у вас есть проблема.

Предполагая, что вы не удаляете файл внезапно из другого потока, это будет простым и очевидным способом сделать это.

Не забывайте, что File.Exists сам по себе может вызвать исключение, поэтому обязательно перехватите его снова.

также, возможно, придется учитывать, какой процент времени он ожидает, что файл будет там
Там нет условий гонки?
не должно быть с ситуацией, которую он описал, но это то, на что я намекал в моем втором абзаце. это может быть легким решением его проблемы, хотя
@ acidzombie24 абсолютно! просто вложите другой блок try / catch. точно так же, как это был любой другой вид блока управления, такой как цикл if или for
Можно ли поймать исключение в исключении?
3

Лучше всего использовать опцию CreateNew при открытии файла для записи.

Нет простого надежного способа проверить наличие файла на диске. Единственное, что вы можете проверить, является ли файлused to and may still существуют на диске, к которому у доступа есть как минимум ограниченная форма доступа.

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

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

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

5

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

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


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

Пожалуйста, проверьте, если вы получаетеSystem.IO.FileNotFoundException когда файл не существует. Попробуйте поймать это вместо IOException.

В самом деле? Когда? Возможно, если это ваше свойство сообщения. В противном случае вы делаете ошибку, которая кусает многих, но не часто, но всегда было трудно найти и исправить. Кажется, я помню какой-то неработающий код при переходе с .NET 1.1 на .NET 2.0 - Microsoft исправила пунктуацию, и пользователи & apos; код сломался в результате. Конечно, Microsoft должно быть разрешено исправлять знаки препинания. И это полностью оставляет локализацию в стороне ...
Хотя я согласен с мнением, я могу думать об исключениях (без каламбура).
"Ты упустил мою точку зрения. Не проверять свойство сообщения, когда-либо & quot; & lt; - возможно, вы его не прочитали, я собирался проверить, существует ли файл через File.Exists. Я не планирую когда-либо проверять текст сообщения
Вы пропустили мою точку зрения. Не проверяйте свойство сообщения, никогда.
это именно проблема. я понятия не имею, как проверить. Я думаю, я мог бы использовать .exist, но это чувствуется неряшливо.
0

Вы можете использовать File.Open и вызывать его сFileMode.OpenOrCreate.

За комментарий: Хорошо, а как насчет FileMode.CreateNew? Затем, если он уже есть, вы получите IOException, в противном случае создайте новый.

@Steven: -1 не был несправедливым ... JP позже отредактировал свой пост, чтобы добавить CreateNew, но первоначально он упомянул только OpenOrCreate;)
О, я понимаю, вы имеете в виду, что он не хочет открывать его, если он уже там?
Это именно то, чего не хочет acidzombie24 ...
Он сказал, что хочет "создать и открыть файл, но только если его не существует". Это именно то, что делает CreateNew. Я дал +1, чтобы компенсировать нечестных -1.
6

Я не уверен, что он вообще хочет открыть файл, если он уже существует.

Я думаю, что он на самом деле послеFileMode.CreateNew это броситIOException если файл уже существует, но в противном случае создаст и откроет его.

но его беспокоили другие причины исключения, такие как «отказано в разрешении»; и т. д. вся суть вопроса заключалась в разграничении возможных причин исключения.
Документация наFileStream конструктор очень сильно подразумевает, что с этим режимомIOException будет выброшен, только если файл уже существует, в противном случае вы получите одно из более производных (и более конкретных исключений). Таким образом, вы правы в том, что обработчик исключений должен будет проверить, является ли фактическим типом исключения (или нет)IOException.

Похожие вопросы