You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中高效按父目录分组排序,实现保留过期父目录下最新符合模式子目录的方法

解决方案:按父目录分组筛选,保留每组最新过期目录

你的思路完全正确——按父目录分组后再处理就是解决这个需求的最优路径。我们可以通过组合LINQ的分组、筛选和排序操作,高效实现“同一父目录下若所有符合模式的子目录都过期,仅保留最新的一个”的逻辑,同时兼顾性能。

核心思路拆解

  1. 精准获取目标目录信息:直接用DirectoryInfo获取目录的元数据(创建时间、父目录等),避免重复IO操作;
  2. 按父目录分组:将所有*_select目录按它们的父目录路径分组,确保同一父目录下的目录被归为一组;
  3. 分情况处理每组:
    • 如果组内有未超过30天的目录:所有过期目录直接标记删除;
    • 如果组内所有目录都已过期:仅保留创建时间最新的那个,其余标记删除;
  4. 批量执行删除:最后统一处理标记的目录,减少零散操作的开销。

完整代码实现

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

class Program
{
    // 预编译正则表达式,提升多次匹配的效率
    private static readonly Regex SelectDirRegex = new Regex(@"_select$", RegexOptions.Compiled);

    static void Main(string[] args)
    {
        string rootPath = @"C:\Main";
        var thirtyDaysAgo = DateTime.Now.AddDays(-30);

        // 1. 获取所有符合模式的目录信息
        var patternDirInfos = new DirectoryInfo(rootPath)
            .GetDirectories("*", SearchOption.AllDirectories)
            .Where(dir => SelectDirRegex.IsMatch(dir.Name)) // 仅匹配目录名结尾为_select的
            .ToList();

        if (!patternDirInfos.Any())
        {
            Console.WriteLine("未找到符合模式的目录");
            return;
        }

        // 2. 按父目录路径分组
        var groupedDirs = patternDirInfos.GroupBy(dir => dir.Parent.FullName);

        // 3. 筛选出需要删除的目录
        var dirsToDelete = new List<DirectoryInfo>();
        foreach (var group in groupedDirs)
        {
            var activeDirs = group.Where(dir => dir.CreationTime > thirtyDaysAgo).ToList();
            var expiredDirs = group.Where(dir => dir.CreationTime <= thirtyDaysAgo).ToList();

            if (activeDirs.Any())
            {
                // 组内有未过期目录,所有过期目录都删除
                dirsToDelete.AddRange(expiredDirs);
            }
            else
            {
                // 组内所有目录都过期,仅保留最新的一个
                var sortedExpired = expiredDirs.OrderByDescending(dir => dir.CreationTime).ToList();
                dirsToDelete.AddRange(sortedExpired.Skip(1));
            }
        }

        // 4. 执行删除操作(添加异常处理避免程序崩溃)
        foreach (var dir in dirsToDelete)
        {
            try
            {
                dir.Delete(true); // true表示递归删除所有子目录和文件
                Console.WriteLine($"成功删除目录:{dir.FullName}");
            }
            catch (IOException ex)
            {
                Console.WriteLine($"删除目录失败(IO异常):{dir.FullName},原因:{ex.Message}");
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine($"删除目录失败(权限不足):{dir.FullName},原因:{ex.Message}");
            }
        }
    }
}

性能优化说明

  • 预编译正则表达式:避免每次匹配都重新编译正则,提升多次调用的效率;
  • 直接使用DirectoryInfo:一次性获取目录的所有元数据,无需后续再调用new DirectoryInfo(),减少IO开销;
  • 分组内排序而非全局排序:仅对每个父目录下的少量目录排序,而非所有目录全局排序,数据量越大优势越明显;
  • 批量处理删除:集中处理删除操作,减少系统调用次数。

额外注意事项

  • 时区问题:如果你的服务器使用UTC时间,建议改用DateTime.UtcNow.AddDays(-30),避免本地时区转换导致的判断误差;
  • 权限问题:确保程序有足够的权限删除目标目录及其内容;
  • 异常处理:添加针对性的异常捕获(如IO异常、权限异常),避免单个目录删除失败导致整个程序终止。

内容的提问来源于stack exchange,提问作者Erelephant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:52:31