简体   繁体   中英

Delete all folders and subdirectories that doesn't have a file of certain extension

I'm using this solution to delete all empty folders and subdirectories in a certain path:

static void Main(string[] args)
{
    processDirectory(@"c:\temp");
}

private static void processDirectory(string startLocation)
{
    foreach (var directory in Directory.GetDirectories(startLocation))
    {
        processDirectory(directory);
        if (Directory.GetFiles(directory).Length == 0 && 
            Directory.GetDirectories(directory).Length == 0)
        {
            Directory.Delete(directory, false);
        }
    }
}

It works perfectly. But I want to delete all empty folders and also folders which are not empty but also doesn't contain files with the .dvr extension.

For example, my folder has the files:

a.log

b.log

c.dvr

d.dat

So this folder can't be deleted, for it contains a file with the dvr extension.

How can I filter it? (I'm using GTK# but I believe C# code will work, since this solution is a C# code)

Unfortunately error handling is very exception based in IO operations. And Directory.Delete throws an IOException if the directory is not empty. So you'll have to delete the files manually:

private static bool processDirectory(string startLocation)
{
    bool result = true;
    foreach (var directory in Directory.GetDirectories(startLocation))
    {
        bool directoryResult = processDirectory(directory);
        result &= directoryResult;

        if (Directory.GetFiles(directory, "*.dvr").Any())
        {
             result = false;
             continue;
        }

        foreach(var file in Directory.GetFiles(directory))
        {
            try
            {
               File.Delete(file);
            }
            catch(IOException)
            {
               // error handling
               result = directoryResult = false;
            }
        }

        if (!directoryResult) continue;
        try
        {
            Directory.Delete(directory, false);
        }
        catch(IOException)
        {
            // error handling
            result = false;
        }
    }

    return result;
}

I would use Directory.EnumerateFiles to see if a directory contains the file you're looking for. Changing your code to be:

static void Main(string[] args)
{
    processDirectory(@"c:\temp");
}

private static void processDirectory(string startLocation)
{
    foreach (var directory in Directory.GetDirectories(startLocation))
    {
        processDirectory(directory);
        if (Directory.GetDirectories(directory).Length == 0  ||
            Directory.EnumerateFiles(directory, "*.dvr").Length == 0
            )
        {
            Directory.Delete(directory, false);
        }
    }
}

Avitus answer is correct, but since you need it to work in .NET 2.0, you cannot use the EnumerateFiles method, however GetFiles gets the job done nicely. But requires a little more code.

Example:

static void Main(string[] args)
{
    processDirectory(@"c:\temp");
}

private static void processDirectory(string startLocation)
{
    foreach (var directory in Directory.GetDirectories(startLocation))
    {
        processDirectory(directory);

        if (Directory.GetDirectories(directory).Length == 0))
        {
            bool delete = false;

            var files = Directory.GetFiles(directory);
            // This will delete the directory if it contains a file with the Extension
            // of .dvr, regardless if there are other files in there. Might be something you want to change.
            for (int i = 0; i < files.Length && !delete; i++)
            {
                delete = files[i].Extension.Equals(".dvr", StringComparison.OrdinalIgnoreCase);
            }

            if (delete)
            {
                // Recursive must be set to true in order to
                // delete files and sub-directories in the folder.
                // This folder will not have any sub-directories
                // so it's only used to delete the files.
                Directory.Delete(directory, /*recursive*/ true);
            }
        }
    }
}

You could, in the spirit of less code move the Directory.Delete method call within the for loop, if you wanted, then break the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM