Исключение кодов или обнаружение исключения типа "файл уже существует"

Пытаясь ответить на этот вопрос, я с удивлением обнаружил, что попытка создать новый файл, когда этот файл уже существует, не вызывает уникальный тип исключения, он просто бросает общий 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 переписать, если он существует. Я думаю, что большинство приложений работают таким образом, даже если есть теоретический риск перезаписи файла, созданного в самый неподходящий момент.