Exception Codes, or Detecting a "File Already Exists" Type Exception

In trying to answer this question, I was surprised to discover that attempting to create a new file when that file already exists does not throw a unique exception type, it just throws a generic IOException.

I am therefore left wondering how to determine if the IOException is the result of an existing file, or some other IO error.

The exception has an HResult, but this property is protected, and thus unavailable to me.

The only other way I can see is to pattern match the message string which feels awful.

example:

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?
}
5

8 Answers

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"); // =)
}

Won't work for temp files etc which might have been deleted again.

Here are my exception best practices:

4

Edit: there is another Hresult that is used when file already exists: 0x800700B7 (-2147024713) "Cannot create a file when that file already exists". Updated the code sample.


When you try to create a new file and it already exists IOException will have Hresult = 0x80070050 (-2147024816).

So you code could look like this:

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 || 
        e.HResult == -2147024713)
    {
        // File already exists.
    }
}
3

To modify @jgauffin, in C# 6, you can use the File.Exists inside of the when clause to avoid entering the catch block and thus behaving more like an actual dedicated exception:

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"))
{
   //...
}

You can place this condition in your catch statement for IOException: if(ex.Message.Contains("already exists")) { ... }. It is a hack, but it will work for all cases that a file exists, even temporary files and such.

1

It's not 100% foolproof (there are other reasons for an IOException), but you can at least exclude all derived exception types:

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
}

or the equivalent:

try
{
    ...
}
catch(UnauthorizedAccessException)
{
    throw;
}
catch(DirectoryNotFoundException)
{
    throw;
}
catch(PathTooLongException)
{
    throw;
}
catch(IOException e)
{
    ... assume file exists
}

As for the linked question, I'd just check for existence, prompt the user to overwrite, then use OpenOrCreate to overwrite if it exists. I think most apps work this way even if there is a theoretical risk of overwriting a file that's created just at the wrong moment.

In C# 6 and later:

const int WARN_WIN32_FILE_EXISTS = unchecked((int)0x80070050);

try
{
    ...
}
catch (IOException e) when (e.HResult == WARN_WIN32_FILE_EXISTS)
{
    ...
}

... or just when (e.HResult == -2147024816), if you're going for "quick and impenetrable". ;-)

(FWIW, the Windows-centric error code has been faithfully copied by Mono and also works on Mac/Linux.)

1

You can't. Unfortunatly IOExceptions are not further specified for some reason beyond my comprehension in the .NET framework.

But in case of creating a new file it is common practice to check if the file exists first. Like so:

       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);
        }

Perhaps not the answer you were looking for. But, c'est ca.

1

You should use

FileMode.Create

instead of

FileMode.CreateNew

It will override a file if its already exists.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest