Karakuri.com

Fintechではたらくアプリケーションエンジニアの技術録

C#と.Net Frameworkで指定したディレクトリ内の空のディレクトリを全て削除する方法

不必要になったファイルを削除することになったのですが、ファイルを削除すりだけではディレクトリ(フォルダ)が残ってしまう結果に。アプリケーションを利用すればすりほどディレクトリが無限に増えるのは気持ち悪いので、ファイルが1つも存在しなくなればディレクトリを削除することにしました。

.Net Frameworkは空ディレクトリだけの削除はできない

.Net Frameworkではサブディレクトリやファイルが存在しない場合は削除するというオプションは用意されていません。

Directory.Delete("c:/...");
Directory.Delete("c:/...", true);

パスだけの指定の場合はディレクトリの中にファイルやサブディレクトリが存在するとIOExceptionがスローされてしまいます。また第2引数は存在するファイルやサブディレクトリごと削除するフラグなのでtrueにすると、ファイルやサブディレクトリが残っているのに削除してしまいます。falseにするとIOExceptionがスローされるだけです…。


IOExceptionをキャッチする強引な手法

考えようによってはIOExceptionがスローされるディレクトリはファイルやサブディレクトリが存在する証ではあります。そのため、この例外を無視して全ディレクトリの削除を実行すればファイルやサブディレクトリが存在しないディレクトリだけを削除することはできます。

var directoryInfo = new DirectoryInfo("c:/...");

foreach(var info in directoryInfo.GetDirectories())
{
   try
   {
       info.delete();
   }
   catch(IOException) { }
}

DirectoryInfoクラスはディレクトリの情報を取得すりクラスです。そのディレクトリの中のフォルダやディレクトリ、親のディレクトリなど様々な情報を取得することができます。しかしこれは良くありません。例外の利用方法としては正しくありません。例外を正常系で使うことになるからです。パフォーマンスの面でも劣ります。

再起を利用してコードを書く

というわけで、ちゃんとファイルとサブディレクトリを確認して削除するかしないかを判断するメソッドを実装するべきです。大学の講義レベルですが、書いてみました。

public void DeleteEmptyDirectories(DirectoryInfo targetDirectoryInfo)
{
   foreach(var subDirectoryInfo in targetDirectoryInfo.GetDirectories())
   {
        foreach (var subSubDirectoryInfo in subDirectoryInfo.GetDirectories())
        {
             DeleteEmptyDirectories(subSubDirectoryInfo);
        }
          
        if (subDirectoryInfo.GetDirectories().Count() == 0 && 
            subDirectoryInfo.GetFiles().Count() == 0)
        {
             subDirectoryInfo.Delete();
        }
   }
}

これで指定したディレクトリ以下の空のディレクトリは削除されるはず。しかしめんどくさいので、標準でやってくれても良い気がしますねー。