tags:

views:

124

answers:

5

I've got a strange situation where deleting and creating directories in quick succession on Windows Server 2008 results in some occasionaly strange errors. Sometimes I get IOExceptions, one time I have had a NotAuthorizedException.

Here is my code that works, but when stepping through in the debugger, lots of exceptions get thrown. In fact I've just had an IOException with 'the directory is not empty' while doing the directory.delete!

Update Quite a few of the responses talk about non atomic directory creation and delayed writes etc. Is there a 100% guaranteed way of making this work? Ideally I would like some system call that is 'DeleteDirectoryAndWaitForTheDirectoryToBeDeleted' and a corresponding system call that is 'CreateDirectoryAndWaitForTheDirectoryToBeCreated'.

Another update I took Neil's code below and tried it on my machine and it failed pretty quickly (after 20 loops). What appears to be happening is that the IDriveE Service has access to the directory and the attempt to create the directory fails with DELETE PENDING. I guess I need to do some more reasearch into things like DELETE PENDING.

Personally I don't like this code as it 'smells' wrong - but it works.

Console.WriteLine("CleanAndCreateDirectory: {0}", baseDirectory);
while (Directory.Exists(baseDirectory))
{
    Console.WriteLine("DeleteDirectory: {0}", baseDirectory);
    try
    {
        Directory.Delete(baseDirectory, true);
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex.Message);
        Thread.Sleep(1000);
    }
}

while (!Directory.Exists(baseDirectory))
{
    try
    {
        Directory.CreateDirectory(baseDirectory);
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex.Message);
    }
}

My suspicions are something watching the file system that causes delays in some operations, but I've no idea what.

+3  A: 

When you delete an item from the file system it doesn't immediately delete it - it marks it for deletion at a later date (also if the directory contains sub-folders / files it will throw an exception).

Mark Ingram
A: 

The problem is that deleting a directory and all of its contents is not an atomic operation. So if anything else adds a file to the directory after the deleting code has 'cleared' the directory, the delete of the directory can fail.

You probably want to have a count on your loops, so that you won't hang if there is a real problem with the deletion or creation.

Douglas Leeder
A: 

Windows also uses something called as 'Delayed Write'. So if you delete a directory its not deleted immediately and its just marked for deletion.

Ankit
+1  A: 

The followinfg C++ code deletes and re-creates directories as fast as is possible with no problems on my old Win2K box. You might like tio try it or similar on your machine.

#include <iostream>
#include <direct.h>
using namespace std;

int main() {
    const char * DIRNAME = "testdir";
    try {
        while(1) {
            if ( rmdir( DIRNAME ) == -1 ) {
             throw "could not remove directory";
         }
         if ( mkdir( DIRNAME ) == -1 ) {
             throw "could not create directory";
         }
        }
    }
    catch( const char * s ) {
     cerr << "Error: " << s << endl;
    }
}
anon
Interesting. It fails on my machine!
Nick R
+1  A: 

Use a FileSystemWatcher to catch the delete and then create your new directory.

JP Alioto