Remove those useless File.Exists calls
I often see code that uses File.Exists(path)
before opening/writing the file. This pattern is very suspect and may leads to unexpected bugs. Let's consider the following code:
if (File.Exists(path))
{
using var stream = File.Open(path, FileMode.Open); // Is it safe?
// ...
}
There are multiple reasons for the previous code to fail. Indeed, other applications running on the machine could change the file between the check and the File.Open
call:
- The file can be deleted by another application (including the antivirus)
- The disk can be removed / unmounted
- The network can be disconnected (network drives)
- The application/service that runs Windows Projected File System (ProjFS) stopped
Also, even if the file exists you may not be able to open it:
- What about permissions?
- What about readonly / hidden files?
- What if the file is locked (file sharing)?
- What if there is an error on the disk?
File.Exists
indicates whether the specified file exists at the moment you check it. The returned value is obsolete as soon as the method returns. If the method returns true, this doesn't mean that the file will still exist when you open it.
Instead of checking if the file/directory exists before doing the action, just do it and handle the possible errors:
try
{
using var stream = File.Open(path, FileMode.Open);
// TODO
}
catch (FileNotFoundException)
{
// TODO
}
catch (DirectoryNotFoundException)
{
// TODO
}
catch (UnauthorizedAccessException)
{
// TODO
}
catch (Exception)
{
// TODO
}
The same applies for Directory operations:
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
// Should be
Directory.CreateDirectory(path);
if (Directory.Exists(path))
{
Directory.Delete(path);
}
// Should be
try
{
Directory.Delete(path);
}
catch(DirectoryNotFoundException)
{
// ok
}
catch(Exception ex)
{
}
#Conclusion
File.Exists
/Directory.Exists
should be used only if you want to know if the file/directory exists at the moment you check it. For instance, you can use it to avoid doing something if the file already exist. Once the method returns, the information is obsolete. Indeed, the file could be created/deleted right after by another application. File.Exists
method is useless if you want to read/write a file. In this case, just do the operation you need to do and handle the exceptions. Anyway, even if the file exists, you may get exceptions for many other reasons.
Do you have a question or a suggestion about this post? Contact me!