Jay*_*Jay 43 .net c# subdirectory
我有一个清理大量目录的任务.我想从一个目录开始并删除任何不包含文件的子目录(无论多深)(文件永远不会被删除,只有目录).如果起始目录不包含任何文件或子目录,则将删除该起始目录.我希望有人可以指出一些现有的代码,而不是重新发明轮子.我将使用C#来做这件事.
Rag*_*czy 88
使用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);
        }
    }
}
Joã*_*elo 39
如果您可以定位.NET 4.0,则可以使用Directory类上的新方法枚举目录,以便在您只想知道是否存在至少一个文件时列出目录中的每个文件时不会造成性能损失.
方法是:
Directory.EnumerateDirectoriesDirectory.EnumerateFilesDirectory.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) { }
}
您还提到目录树可能非常深,因此如果您探测的路径太长,可能会出现一些异常.
在目前为止提到的3种方法上运行C:\ Windows 1000次测试产生了这样的结果:
GetFiles+GetDirectories:630ms
GetFileSystemEntries:295ms
EnumerateFileSystemEntries.Any:71ms
在空文件夹上运行它会产生这种情况(再次1000次):
GetFiles+GetDirectories:131ms
GetFileSystemEntries:66ms
EnumerateFileSystemEntries.Any:64ms
因此,当您检查空文件夹时,EnumerateFileSystemEntries是最好的整体.
这是一个利用并行执行的版本,在某些情况下可以更快地完成任务:
public static void DeleteEmptySubdirectories(string parentDirectory){
  System.Threading.Tasks.Parallel.ForEach(System.IO.Directory.GetDirectories(parentDirectory), directory => {
    DeleteEmptySubdirectories(directory);
    if(!System.IO.Directory.EnumerateFileSystemEntries(directory).Any()) System.IO.Directory.Delete(directory, false);
  });   
}
这是单线程模式下的相同代码:
public static void DeleteEmptySubdirectoriesSingleThread(string parentDirectory){
  foreach(string directory in System.IO.Directory.GetDirectories(parentDirectory)){
    DeleteEmptySubdirectories(directory);
    if(!System.IO.Directory.EnumerateFileSystemEntries(directory).Any()) System.IO.Directory.Delete(directory, false);
  }
}
...这里有一些示例代码,您可以使用它来测试场景中的结果:
var stopWatch = new System.Diagnostics.Stopwatch();
for(int i = 0; i < 100; i++) {
  stopWatch.Restart();
  DeleteEmptySubdirectories(rootPath);
  stopWatch.Stop();
  StatusOutputStream.WriteLine("Parallel: "+stopWatch.ElapsedMilliseconds);
  stopWatch.Restart();
  DeleteEmptySubdirectoriesSingleThread(rootPath);
  stopWatch.Stop();
  StatusOutputStream.WriteLine("Single: "+stopWatch.ElapsedMilliseconds);
}
...以下是我的计算机针对广域网文件共享上的目录的一些结果。此共享当前只有 16 个子文件夹和 2277 个文件。
Parallel: 1479
Single: 4724
Parallel: 1691
Single: 5603
Parallel: 1540
Single: 4959
Parallel: 1592
Single: 4792
Parallel: 1671
Single: 4849
Parallel: 1485
Single: 4389
| 归档时间: | 
 | 
| 查看次数: | 31611 次 | 
| 最近记录: |