fletchsod
fletchsod

Reputation: 3719

Proper way to delete files & directories inside but leave directory path alone?

In the script below, I want to preserve the "Dominion" folder without having it be deleted. Problem is this Directory.Delete command delete the "Dominion" folder.

var directoryPath = "X:\Applications\Dealer\Data\Ftp\Incoming";

if (Directory.Exists(directoryPath + @"\" + "Dominion"))  
{
    Directory.Delete(directoryPath + @"\" + "Dominion", true);
}
Directory.CreateDirectory(directoryPath + @"\" + "Dominion");  

Upvotes: 0

Views: 198

Answers (3)

Tim Schmelter
Tim Schmelter

Reputation: 460098

You could use this approach:

var root = new DirectoryInfo(@"X:\Applications\Dealer\Data\Ftp\Incoming");
var deleteableEntries = root.EnumerateFileSystemInfos()
    .Where(entry => (entry.Attributes & FileAttributes.Directory) != FileAttributes.Directory || entry.Name != "Dominion");
foreach(var entryToDelete in deleteableEntries)
    entryToDelete.Delete();

Since this will fail for several reasons(access-denied or folders which aren't empty), here is a rather untested approach which should work or at least give an idea:

var stack = new Stack<FileSystemInfo>(deleteableEntries); // "recursive", stack to delete deepest folders first

while (stack.Count > 0)
{
    FileSystemInfo fsi = stack.Peek();  // don't remove yet, only if it was deleted
    bool isDirectory = (fsi.Attributes & FileAttributes.Directory) == FileAttributes.Directory;
    fsi.Attributes = FileAttributes.Normal; // can avoid possible access-denied exceptions if it's readonly
    try
    {
        bool canBeDeleted = !isDirectory;
        if (isDirectory)
        {
            var subEntries = new DirectoryInfo(fsi.FullName).EnumerateFileSystemInfos("*.*", SearchOption.AllDirectories);
            canBeDeleted = !subEntries.Any();
            foreach (FileSystemInfo subEntry in subEntries)
                stack.Push(subEntry);
        }
        if (canBeDeleted)
        {
            fsi.Delete();
            stack.Pop(); // remove it
        }
    } catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
    }
}

Upvotes: 2

ragerory
ragerory

Reputation: 1378

You could probably simplify this to a delegate, but it's pretty simple to get the files and loop through them.

var directoryPath = "X:\Applications\Dealer\Data\Ftp\Incoming";

if (Directory.Exists(directoryPath + @"\" + "Dominion"))  
{
    var newPath = directoryPath + @"\" + "Dominion";
    var files = Directory.GetAllFiles(newPath);

    foreach (var file in files)
    {
        File.Delete(file);
    }
}

Upvotes: 1

Thomas Ayoub
Thomas Ayoub

Reputation: 29431

Just use this :

var directoryPath = @"X:\Applications\Dealer\Data\Ftp\Incoming";
System.IO.DirectoryInfo directoryToClean = new DirectoryInfo(directoryPath );

foreach (FileInfo file in directoryToClean.GetFiles())
{
    file.Delete(); 
}
foreach (DirectoryInfo dir in directoryToClean.GetDirectories().Where(dir => dir.Name != "Dominion"))
{
    dir.Delete(true);
}

Upvotes: 1

Related Questions