У меня есть задача очистить большое количество каталогов. Я хочу запуститься в каталоге и удалить любые подкаталоги (неважно, как глубоко), которые не содержат файлов (файлы никогда не будут удаляться, только каталоги). Начальный каталог будет затем удален, если он не будет содержать файлов или подкаталогов. Я надеялся, что кто-то мог указать на меня на некоторый существующий код для этого вместо того, чтобы иметь необходимость изобрести велосипед. Я буду делать это использование C#.
Использование кода 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);
}
}
}
Если вы можете настроить таргетинг на .NET 4.0, вы можете использовать новые методы класса Directory
для перечисления каталогов, чтобы платите штраф за производительность, перечисляя каждый файл в каталоге, когда вы просто хотите знать, есть ли хотя бы один.
Это следующие методы:
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) { }
}
Вы также упоминаете, что дерево каталогов может быть очень глубоким, поэтому оно возможно, вы можете получить некоторые исключения, если исследуемый путь слишком длинный.
Отсюда Сценарий 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
}
}
Примечание : используйте на свой страх и риск!