Исключение кодов или обнаружение исключения типа "файл уже существует"
Пытаясь ответить на этот вопрос, я с удивлением обнаружил, что попытка создать новый файл, когда этот файл уже существует, не вызывает уникальный тип исключения, он просто бросает общий IOException
.
Поэтому мне остается задаться вопросом, как определить, является ли IOException
результатом существующего файла или некоторой другой ошибки ввода-вывода.
Исключение имеет HResult, но это свойство защищено и, таким образом, недоступно для меня.
Единственный другой способ, который я вижу, - сопоставить шаблон с строкой сообщения, которая кажется ужасной.
Пример:
try
{
using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//write file
}
}
catch (IOException e)
{
//how do I know this is because a file exists?
}
Ответы
Ответ 1
try
{
using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//write file
}
}
catch (IOException e)
{
var exists = File.Exists(@"C:\Text.text"); // =)
}
Не будет работать для файлов temp и т.д., которые могли быть удалены снова.
Ответ 2
Вы можете поместить это условие в свою инструкцию catch для исключения IOException: if(ex.Message.Contains("already exists")) { ... }
. Это взлом, но он будет работать во всех случаях, когда файл существует, даже временные файлы и т.д.
Ответ 3
Чтобы изменить @jgauffin, в С# 6, вы можете использовать File.Exists
внутри предложения when
, чтобы избежать ввода блока catch
и, следовательно, более похоже на фактическое выделенное исключение:
try
{
using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//write file
}
}
catch (IOException e) when (File.Exists(@"C:\Text.text"))
{
//...
}
Ответ 4
При попытке создать новый файл и уже существует IOException будет Hresult = 0x80070050 (-2147024816)
.
Итак, вы можете выглядеть так:
try
{
using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//write file
}
}
catch (IOException e)
{
if (e.HResult == -2147024816)
{
// File already exists.
}
}
Ответ 5
Вы должны использовать
FileMode.Create
вместо
FileMode.CreateNew
Он будет переопределять файл, если он уже существует.
Ответ 6
Вы не можете. К сожалению, IOExceptions не уточняются по какой-либо причине, кроме моего понимания в .NET framework.
Но в случае создания нового файла обычная практика - проверить, существует ли файл первым. Например:
try
{
if (File.Exists("C:\\Test.txt"))
{
//write file
using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//The actual writing of file
}
}
}
catch (IOException ex)
{
//how do I know this is because a file exists?
Debug.Print(ex.Message);
}
Возможно, не тот ответ, который вы искали. Но, c'est ca.
Ответ 7
Это не 100% надежный (есть другие причины для исключения IOException), но вы можете, по крайней мере, исключить все производные типы исключений:
try
{
...
}
catch(IOException e)
{
if (e is UnauthorizedAccessException) throw;
if (e is DirectoryNotFoundException) throw;
if (e is PathTooLongException) throw;
// etc for other exceptions derived from IOException
... assume file exists
}
или эквивалент:
try
{
...
}
catch(UnauthorizedAccessException)
{
throw;
}
catch(DirectoryNotFoundException)
{
throw;
}
catch(PathTooLongException)
{
throw;
}
catch(IOException e)
{
... assume file exists
}
Что касается связанного вопроса, я просто проверю наличие, попрошу перезаписать пользователя, а затем OpenOrCreate
переписать, если он существует. Я думаю, что большинство приложений работают таким образом, даже если есть теоретический риск перезаписи файла, созданного в самый неподходящий момент.