user1384603
user1384603

Reputation: 565

How to check if path is valid without using try-catch?

I want to check if a folder exists and if not then create it. But I don't know if the path supplied will even valid. When the path is not valid the following happens.

string path = "this is an invalid path";

if (!Directory.Exists(path))
    Directory.CreateDirectory(path); //Exception thrown here

If you supply an invalid path, it will throw a DirectoryNotFoundException exception.

How can I stop this exception from occurring? I don't want to use a try-catch. I want to detect that this exception will occur even before the exception happens.

Upvotes: 4

Views: 17743

Answers (7)

Ian Goldby
Ian Goldby

Reputation: 6186

I think the simplest way to test if a path is valid and the file exists without raising an exception in C# is to call the unmanaged function PathFileExists directly in shlwapi.dll.

[DllImport("shlwapi.dll", EntryPoint = "PathFileExistsW",  SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PathFileExists([MarshalAs(UnmanagedType.LPTStr)]string pszPath);

Note that as David writes in his answer, you might nevertheless get an exception when you try to create the directory.

Upvotes: 0

Akshita
Akshita

Reputation: 867

try this

string path = "this is an invalid path";

        if (Path.IsPathRooted(path)
        {
            Directory.CreateDirectory(path); 
        }

Upvotes: 0

Beachwalker
Beachwalker

Reputation: 7915

Why don't you want to catch (specific) Exceptions? It is considered as a good practice... anyway, these are my solutions without try/catch:

  1. solution:

    string path = "C:\test";
    if (!Directory.Exists(path) && path.IndexOfAny(Path.GetInvalidFileNameChars()) == -1)
    {
        Directory.CreateDirectory(path);
    }
    
  2. solution:

    string path = "C:\test";
    var canCreate = true;
    foreach (var c in path.Where(Path.GetInvalidFileNameChars().Contains))
    {
        canCreate = false;
    }
    
    if (canCreate && !Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }
    
  3. solution:

    if (path.Any(c => Path.GetInvalidFileNameChars().Contains(c)) && !Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }
    

Please, be aware that this code can still fail... e.g. think about SecurityExeption (do you have the credentionals to create a directory there?!?

Also be aware there is still a (little) chance that the directory has been created (by another process/thread/...) after your test with Exists() but before your call of CreateDirectory(). These are two calls and they are not atomic (together) when querying/modifying the file system.

Upvotes: 3

Marlon Vidal
Marlon Vidal

Reputation: 669

You can use a single if-else statement

if(!Directory.Exists(path))
   Directory.CreateDirectory(path)
else
   //Show user a custom error message

Upvotes: -1

David Heffernan
David Heffernan

Reputation: 613302

The explanation for the failure of your code is that the path is invalid. The documentation says:

DirectoryNotFoundException

The specified path is invalid (for example, it is on an unmapped drive).

Trying to predict in advance whether or not a directory can be created is a devil of a job. You'd need to account for security, OS name rules and limits, file system name rules and limits, and whether or not drives are mapped. And probably lots more concerns. I would not contemplate re-implementing what the system provides for free.

In any case, whilst you can call Directory.Exists, you do still need to allow for an exception being thrown. If the file system changes between the call to Directory.Exists and the subsequent call to Directory.CreateDirectory, then an exception will be raised. For example, if another process creates the directory that you are trying to create. Granted, this is a rather unlikely event, but it's perfectly possible.

In summary, the best option, by a distance, is to catch the exception. As the well known saying goes, it's better to ask for forgiveness than to ask for permission.

Upvotes: 8

Joshua Honig
Joshua Honig

Reputation: 13215

You can also use Path.GetInvalidFileNameChars() to check whether the directory name supplied is valid for a new directory name:

// Directory.Exists will return false because path is not even valid
var path = "1:1 comparison?";
var firstBad = Path.GetInvalidFileNameChars().Cast<char?>()
                   .FirstOrDefault(c => path.Contains(c.Value));
if (firstBad != null)
    Console.WriteLine("Char '{0}' is invalid for a directory name", firstBad.Value);

Upvotes: 0

Habib
Habib

Reputation: 223302

Use Directory.Exists method to check if a folder exists

if(Directory.Exists(path))
{
  //Directory exists
}
else
{
 // doesn't exist
}

Remember to include System.IO;

Upvotes: 10

Related Questions