Monday, June 29, 2015

Temporary Directory

I needed a way to make sure a folder was deleted after using it in a unit test, this was what I came up with...

To create a new folder with "." as the parent folder:
TemporaryDirectory.CreateNew(".")


To wrap a round a previously created folder "C:\Temp\unit_test":
TemporaryDirectory.Wrap("C:\Temp\unit_test")


Sample unit test:
[TestMethod]
public void create_remove()
{
    string folderPath;
    using (var folder = TemporaryDirectory.CreateNew("."))
    {
        folderPath = folder.Folder;
        var path = Path.Combine(folderPath, "test.txt");
        File.WriteAllText(path, "Test");
    }
    Assert.IsFalse(Directory.Exists(folderPath));
}


And finaly the TemporaryDirectory class, with a DeleteDirectory method that ensures the deletion of the folder even if its open in Windows Explorere.
public sealed class TemporaryDirectory : IDisposable
{
    private static int MaximumAttempts = 10;
    public string Folder { get; private set; }

    private TemporaryDirectory(string path)
    {
        Folder = Path.GetFullPath(path);
        Directory.CreateDirectory(Folder);
    }

    public void Dispose()
    {
        DeleteDirectory(Folder);
    }

    public static TemporaryDirectory CreateNew(string pathToParentDirectory)
    {
        var path = Path.Combine(pathToParentDirectory, Guid.NewGuid().ToString());
        return new TemporaryDirectory(path);
    }

    public static TemporaryDirectory Wrap(string path)
    {
        return new TemporaryDirectory(path);
    }

    public static void DeleteDirectory(string path)
    {
        if (path == null) throw new ArgumentNullException("path");
        var attempts = 0;
        var exists = Directory.Exists(path);
        while (exists)
        {
            try
            {
                attempts++;
                if (Directory.Exists(path)) Directory.Delete(path, true);
                exists = false;
            }
            catch (IOException)
            {
                Thread.Yield();
                if (attempts >= MaximumAttempts) throw;
            }
            catch (UnauthorizedAccessException)
            {
                Thread.Yield();
                if (attempts >= MaximumAttempts) throw;
            }
        }
    }
}

No comments:

Post a Comment