Search code examples
c#.netdirectoryatomic

Create directory only if not exists (.NET)


Is there a way to be sure that I am the one that created a directory in C#?

By default, Directory.CreateDirectory is essentially an UPSERT operation: if the directory doesn't exist, it is created, but if it does already exist, well that's just fine. As long as it exists on return, everybody is happy.

But, I intend to delete the subtree when I'm done with it, and I don't want to do that if I didn't create it in the first place. As far as I can tell, the only way to achieve this will be P/Invoke because with the managed API, I must test for existence separately and there will always be a race condition between Directory.Exists and Directory.CreateDirectory.

In the underlying platform API, though, the call to create a directory will return an error if it already exists (ERROR_ALREADY_EXISTS from CreateDirectoryW on Windows, EEXIST from mkdir on POSIX systems).

Is there a managed way to create a directory but only if it doesn't exist in .NET?


Solution

  • @rotabor's answer of creating a directory elsewhere and then using Directory.Move to try to put it into place has a gap in that "creating a directory elsewhere" has exactly the same race condition problem -- but .NET provides a function Directory.CreateTempSubdirectory that can plug that gap. First use Directory.CreateTempSubdirectory to establish a directory that you know you were the creator of, then use Directory.Move to move it the target path. That may fail, even if you checked Directory.Move beforehand, because of the possibility of some other process sneaking in ahead of you, and then you can try a different path and loop or handle it otherwise as needed.

    Also, if you don't need a specific target path, just some path that you own, then you can simply use Directory.CreateTempSubdirectory and be done with it.