C# 递归删除空文件夹,直到在目录树中找到非空目录

C# 递归删除空文件夹,直到在目录树中找到非空目录,c#,recursion,C#,Recursion,我有一个基于GUID构建图像文件夹的大量图像的体系结构: C:\AdPictures\7e\42\1a\dc-7\3b\7-\4e\c2-9\ee\f-\f2\4c\7d\4a\32\14\ 我需要进行递归删除,直到从文件夹“14”到目录“7e”的文件夹不是空的(“AdPictures”文件夹需要保留,因为它是根文件夹) 我发现: Directory.Delete(folderPath, true); 但当使用时,它会删除所有内容 如何实现从底部开始删除所有空目录并在找到树上的非空目录后停止

我有一个基于GUID构建图像文件夹的大量图像的体系结构:

C:\AdPictures\7e\42\1a\dc-7\3b\7-\4e\c2-9\ee\f-\f2\4c\7d\4a\32\14\

我需要进行递归删除,直到从文件夹“14”到目录“7e”的文件夹不是空的(“AdPictures”文件夹需要保留,因为它是根文件夹)

我发现:

Directory.Delete(folderPath, true); 
但当使用时,它会删除所有内容

如何实现从底部开始删除所有空目录并在找到树上的非空目录后停止的方法

我的解决方案应该使用递归。

基本的递归模型

void checkDIR(string Path)
{
//Path will equal AddImage right? 
   foreach(string childpath in Directory.GetDirectories(path))
    {
         //so here we are calling checkpaths for 7E GUID Directory Structure
         checkpaths(childpath);

    }
}

void checkpaths(string Path)
{



   foreach(string childpath in Directory.GetDirectories(path))
    {  //here we dig deeper
         checkpaths(childpaths);//recursion


    }
    //the first recursion to get here will be the deepest directory
   //we are now in '14'

   if(there are any files)
   {do what you want}
   else
   {
    do what you need
   }

}
您可能需要一些标志或其他计数器和变量来测试和跟踪事物,但这正是您需要的。只要在
检查路径中调用delete
添加图像
将不会被删除

您就可以使用和。使用递归的可能解决方案如下所示:

private void deleteEmptyDirectories(String path)
{
    var di = new DirectoryInfo(path);
    // if directory is empty
    if (di.GetFiles().Count() == 0 && di.GetDirectories().Count() == 0)
    {
        di.Delete(); // it
        // and go one up
        deleteEmptyDirectories(di.Parent.FullName);
    }
    // else stop (recursion) here
}
var start = @"c:\path\to\sub\directory\";
deleteEmptyDirectories(start);
该函数可按如下方式使用:

private void deleteEmptyDirectories(String path)
{
    var di = new DirectoryInfo(path);
    // if directory is empty
    if (di.GetFiles().Count() == 0 && di.GetDirectories().Count() == 0)
    {
        di.Delete(); // it
        // and go one up
        deleteEmptyDirectories(di.Parent.FullName);
    }
    // else stop (recursion) here
}
var start = @"c:\path\to\sub\directory\";
deleteEmptyDirectories(start);
试试这个:

var dir = "a/b/c/d";
white (true) {
    If (Directory.EnumerateFiles(dir).Any() || 
        Directory.EnumerateDirectories(dir).Any()) break;

    Directory.Delete(dir);

    dir = Path.GetDirectoryName(dir);
 }
如果我正确理解你的问题,这将删除所有文件夹,直到找到一个不是空的

编辑

只需更改为:

var dir = "a/b/c/d";
white (!Directory.EnumerateFiles(dir).Any() && 
       !Directory.EnumerateDirectories(dir).Any()) {
    Directory.Delete(dir);

    dir = Path.GetDirectoryName(dir);
 }

请尝试以下代码示例。
它用于删除指定父文件夹的所有空子文件夹,包含两种方法:

  • 第一种方法
    removemptyfolders
    只是列出一个文件夹的子文件夹 指定的文件夹,并为每个文件夹调用第二个方法
  • 第二个
    removemptysubfolders
    被调用 递归地检查特定子文件夹的树是否为空 如果是,则删除它 守则:

    private void RemoveEmptyFolders(string path)
    {
        foreach (string subFolder in Directory.GetDirectories(path))
            RemoveEmptySubFolders(subFolder);
    }
    
    private bool RemoveEmptySubFolders(string path)
    {
        bool isEmpty = Directory.GetDirectories(path).Aggregate(true, (current, subFolder) => current & RemoveEmptySubFolders(subFolder))
            && Directory.GetFiles(path).Length == 0;
        if (isEmpty)
            Directory.Delete(path);
        return isEmpty;
    }
    
    用法:

    RemoveEmptyFolders(@"C:\AdPictures");
    

    但是,如果需要删除以“14”结尾的特定子树,则不需要递归,所有其他答案都可以满足您的需要。

    下面是递归方法

    DirectoryInfo dir = new DirectoryInfo(folderPath);
    DeleteFolderIfEmpty(dir);
    
    
    public void DeleteFolderIfEmpty(DirectoryInfo dir){
       if(dir.EnumerateFiles().Any() || dir.EnumerateDirectories().Any())
            return;
       DirectoryInfo parent = dir.Parent;
       dir.Delete();
    
       // Climb up to the parent
       DeleteFolderIfEmpty(parent);
    }
    
    防止删除根目录

    DirectoryInfo dir = new DirectoryInfo(folderPath);
    DeleteFolderIfEmpty(dir);
    
    
    public void DeleteFolderIfEmpty(DirectoryInfo dir){
       if(dir.EnumerateFiles().Any() || dir.EnumerateDirectories().Any())
            return;
    
       if(dir.FullName == @"c:\folder\root")
            return;
    
       DirectoryInfo parent = dir.Parent;
       dir.Delete();
    
       // Climb up to the parent
       DeleteFolderIfEmpty(parent);
    }
    

    您正在删除包含所有其他目录的父目录进入它们检查它们然后删除目录结构是否如图所示是线性的还是会分支出来?因此dc-7可能会分支两个以上的子目录,但您不想从那里开始您想从14开始-gotchaI打算谈谈checkDirectory调用;)@RadioSpace修复了它-我在粘贴代码之前将名称更改为
    deleteEmptyDirectories
    ,忘记了递归调用;-)@RadioSpace阅读了MSDN上的文档并进行了尝试。这是可能的。我认为.NET Framework在内部会向上移动一个目录,然后删除指定的目录。您可以使用
    !bla.Any()
    而不是
    bla.Count()==0
    这可以通过向函数添加第二个参数来轻松完成,例如:
    string stopAtDirectory
    ,然后检查当前目录名是否等于指定的字符串。您好,谢谢。是的,这是正确的,但我想避免使用while(true)函数…您好,谢谢,但我想从路径的末尾转到根,如果我发现一个非空的folder@Patrick你知道最深目录的名字吗?虽然这种递归结构从根目录开始,但a/b/c的检查路径在a/b/c/d完成之前不会结束,所以这已经是像这样的a类设置了。因为它将在c之前检查d,所以这完全取决于如何在CheckPath中的foreach循环之前和之后设置代码的文件检查部分。我很难解释。糟糕的命名约定,C#不建议使用字母较小的方法名称,用不同的case方法名称创建具有不同逻辑的方法是糟糕的设计。嗨,我已经测试过了,但它不起作用,因为起始路径必须是C:\AdPictures\7e\42\1a\dc-7\3b\7-\4e\c2-9\ee\f-\f2\4c\7d\4a\32\14\并且它将上升到C:\AdPictures\如果根不是空的,它将停止,你想保留根吗?嗨,我刚刚测试过,它工作正常!看来赏金已经过期了,你知道我该怎么给你吗?