【问题标题】:Recursively delete empty folders until not empty directory is found up the dir-tree递归删除空文件夹,直到在目录树上找到不空目录
【发布时间】:2014-04-29 12:56:16
【问题描述】:

我有一个基于 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); 

但使用时会删除所有内容。

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

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

【问题讨论】:

  • 您正在删除包含所有其他目录的父目录进入它们检查'em然后删除
  • 目录结构是线性的还是会分支出来的?
  • 所以 dc-7 可能会再分出两个孩子,但你不想从那里开始你想从 14 岁开始 - 明白了

标签: c# recursion


【解决方案1】:

getdirectories msdn

基本递归模型。

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
   }

}

您可能需要一些标志或其他计数器和变量来测试和跟踪事物,但这正是您要寻找的。只要你在checkpaths中调用deleteaddimage就不会被删除

【讨论】:

  • 您好,谢谢,但我想从路径的末尾转到根目录,如果我发现一个非空文件夹就停止
  • @Patrick 你知道最深目录的名称吗?虽然这种递归结构从根目录开始,但 a/b/c 的检查路径在 a/b/c/d 完成之前不会结束,所以这已经是一种类似的设置。因为它将在 c 之前检查 d 这一切都取决于您如何在检查路径中的 foreach 循环之前和之后设置文件检查部分代码。我很难解释。
【解决方案2】:

您可以使用DirectoryInfo.Delete()DirectoryInfo.Parent property。使用递归的可能解决方案如下所示:

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);

【讨论】:

  • 我正要对 checkDirectory 调用说点什么;)
  • @RadioSpace 已修复 - 我在粘贴代码之前将名称更改为 deleteEmptyDirectories 并忘记了递归调用 ;-)
  • @RadioSpace 阅读 MSDN 上的文档并尝试一下。有可能的。我认为 .NET Framework 内部会向上移动一个目录,然后删除指定的目录。
  • 你可以使用!bla.Any()而不是bla.Count() == 0
  • 这可以通过在函数中添加第二个参数来轻松完成,例如:string stopAtDirectory,然后检查当前目录名称是否等于指定的字符串。
【解决方案3】:

试试这个:

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);
 }

如果我完全理解你的问题,tren 这将删除所有文件夹,直到找到一个不为空的文件夹。

编辑

简单地改成这样:

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

    dir = Path.GetDirectoryName(dir);
 }

【讨论】:

  • 嗨,谢谢。是的,这是正确的,但我想避免使用 while(true) 函数...
【解决方案4】:

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

  1. 第一种方法RemoveEmptyFolders 简单地列出一个子文件夹 指定文件夹并为每个文件夹调用第二种方法。
  2. 第二个RemoveEmptySubFolders被调用 递归检查特定子文件夹的树是否为空 如果是,则将其删除。

代码:

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' 结尾的特定子树,你不需要递归,所有其他答案都满足你的需要。

【讨论】:

  • Bad Naming Convention,C# 不建议使用小写字母的方法名,用不同的 case 方法名创建具有不同逻辑的方法是不好的设计。
  • 嗨,我已经测试过了,但它不起作用,因为起始路径必须是 C:\AdPictures\7e\42\1a\dc-7\3b\7-\4e\c2-9\ee \f-\f2\4c\7d\4a\32\14\ 并且它会上升到 C:\AdPictures\ 并停止
【解决方案5】:

这里是递归方法。

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);
}

【讨论】:

  • 如果Root不为空就停止,你想保留Root即使为空?
  • 您好,我刚刚测试过,它工作正常!赏金好像过期了,你知道我怎么给你吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 2014-06-21
  • 2012-03-21
  • 2014-05-12
相关资源
最近更新 更多