54

多数のディレクトリをクリーンアップするタスクがあります。ディレクトリから開始し、ファイルを含まないサブディレクトリ (深さに関係なく) を削除します (ファイルは削除されず、ディレクトリのみが削除されます)。ファイルまたはサブディレクトリが含まれていない場合、開始ディレクトリは削除されます。車輪を再発明するのではなく、誰かがこれのための既存のコードを教えてくれることを望んでいました. これを C# を使用して実行します。

4

9 に答える 9

108

C# コードの使用。

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);
        }
    }
}
于 2010-05-11T14:44:32.033 に答える
49

.NET 4.0をターゲットにできる場合は、Directoryクラスの新しいメソッドを使用してディレクトリを列挙し、少なくとも1つあるかどうかを知りたいときに、ディレクトリ内のすべてのファイルを一覧表示する際のパフォーマンスの低下を防ぐことができます。

方法は次のとおりです。

  • Directory.EnumerateDirectories
  • Directory.EnumerateFiles
  • Directory.EnumerateFileSystemEntries

再帰を使用した可能な実装:

static void Main(string[] args)
{
    DeleteEmptyDirs("Start");
}

static void DeleteEmptyDirs(string dir)
{
    if (String.IsNullOrEmpty(dir))
        throw new ArgumentException(
            "Starting directory is a null reference or an empty string", 
            "dir");

    try
    {
        foreach (var d in Directory.EnumerateDirectories(dir))
        {
            DeleteEmptyDirs(d);
        }

        var entries = Directory.EnumerateFileSystemEntries(dir);

        if (!entries.Any())
        {
            try
            {
                Directory.Delete(dir);
            }
            catch (UnauthorizedAccessException) { }
            catch (DirectoryNotFoundException) { }
        }
    }
    catch (UnauthorizedAccessException) { }
}

また、ディレクトリツリーが非常に深い可能性があるため、プローブするパスが長すぎる場合に例外が発生する可能性があることにも言及しました。

于 2010-05-11T14:55:12.020 に答える
11

これまでに述べた 3 つの方法で C:\Windows で 1000 回テストを実行すると、次の結果が得られました。

GetFiles+GetDirectories:630ms
GetFileSystemEntries:295ms
EnumerateFileSystemEntries.Any:71ms

空のフォルダーで実行すると、次のようになりました(1000回繰り返します):

GetFiles+GetDirectories:131ms
GetFileSystemEntries:66ms
EnumerateFileSystemEntries.Any:64ms

したがって、空のフォルダーをチェックする場合は、EnumerateFileSystemEntries が全体的に断然優れています。

于 2014-04-14T13:16:07.727 に答える
3

空のディレクトリのみを削除することに依存している場合DirectoryInfo.Deleteは、簡潔な拡張メソッドを記述できます

public static void DeleteEmptyDirs(this DirectoryInfo dir)
{
    foreach (DirectoryInfo d in dir.GetDirectories())
        d.DeleteEmptyDirs();

    try { dir.Delete(); }
    catch (IOException) {}
    catch (UnauthorizedAccessException) {}
}

使用法:

static void Main()
{
    new DirectoryInfo(@"C:\temp").DeleteEmptyDirs();
}
于 2012-03-14T16:57:34.083 に答える
3

ここから、空のディレクトリを削除する Powershell スクリプト:

$items = Get-ChildItem -Recurse

foreach($item in $items)
{
      if( $item.PSIsContainer )
      {
            $subitems = Get-ChildItem -Recurse -Path $item.FullName
            if($subitems -eq $null)
            {
                  "Remove item: " + $item.FullName
                  Remove-Item $item.FullName
            }
            $subitems = $null
      }
}

:自己責任で使用してください!

于 2010-05-11T14:28:55.897 に答える
0
//Recursive scan of empty dirs. See example output bottom

string startDir = @"d:\root";

void Scan(string dir, bool stepBack)
    {
        //directory not empty
        if (Directory.GetFileSystemEntries(dir).Length > 0)
        {
            if (!stepBack)
            {
                foreach (string subdir in Directory.GetDirectories(dir))
                    Scan(subdir, false);
            } 
        }
        //directory empty so delete it.
        else
        {
            Directory.Delete(dir);
            string prevDir = dir.Substring(0, dir.LastIndexOf("\\"));
            if (startDir.Length <= prevDir.Length)
                Scan(prevDir, true);
        }
    }
//call like this
Scan(startDir, false);

/*EXAMPLE outputof d:\root with empty subfolders and one filled with files
   Scanning d:\root
   Scanning d:\root\folder1 (not empty)
   Scanning d:\root\folder1\folder1sub1 (not empty)
   Scanning d:\root\folder1\folder1sub1\folder2sub2 (deleted!)
   Scanning d:\root\folder1\folder1sub1 (deleted!)
   Scanning d:\root\folder1 (deleted)
   Scanning d:\root (not empty)
   Scanning d:\root\folder2 (not empty)
   Scanning d:\root\folder2\folder2sub1 (deleted)
   Scanning d:\root\folder2 (not empty)
   Scanning d:\root\folder2\notempty (not empty) */
于 2013-05-22T10:04:40.193 に答える