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

C#中统计指定目录内容时排除.git目录及其中文件的方法

解决统计目录文件/数量时排除.git文件夹的问题

我明白你遇到的困扰了——原来的代码只排除了顶层的.git目录,但GetFiles用SearchOption.AllDirectories会直接递归所有子目录,包括.git内部的文件,所以那些文件还是会被统计进去,根本没被过滤掉。

为什么原来的方法失效?

Directory.GetFiles和Directory.GetDirectories是独立执行的:

  • 你过滤GetDirectories的结果只是排除了.git目录本身,但GetFiles依然会遍历所有子目录(包括.git里的)
  • 用EndsWith(".git")判断目录也有风险,如果路径里有其他类似结尾的目录(比如my.git.backup),会误判,最好用Path.GetFileName(dir) == ".git"来精准匹配目录名

推荐解决方案:手动递归遍历(高效且准确)

这种方法会在遍历过程中直接跳过.git目录,不会浪费资源去遍历它的内部内容:

public static void CountItemsExcludingGit(string targetPath, out int fileCount, out int directoryCount)
{
    fileCount = 0;
    directoryCount = 0;

    try
    {
        // 统计当前目录下的所有文件
        fileCount += Directory.GetFiles(targetPath).Length;

        // 获取当前目录下的子目录,直接排除名为.git的目录
        var validSubDirectories = Directory.GetDirectories(targetPath)
                                           .Where(dir => Path.GetFileName(dir) != ".git");
        
        // 统计当前目录下的有效子目录数量
        directoryCount += validSubDirectories.Count();

        // 递归遍历每个有效子目录
        foreach (var subDir in validSubDirectories)
        {
            int subFileCount, subDirCount;
            CountItemsExcludingGit(subDir, out subFileCount, out subDirCount);
            fileCount += subFileCount;
            directoryCount += subDirCount;
        }
    }
    catch (UnauthorizedAccessException)
    {
        // 可选:处理权限不足的情况,比如跳过无法访问的目录
        Console.WriteLine($"无法访问目录:{targetPath}");
    }
    catch (DirectoryNotFoundException)
    {
        // 可选:处理目录不存在的情况
        Console.WriteLine($"目录不存在:{targetPath}");
    }
}

使用方式很简单:

int totalFiles, totalDirs;
CountItemsExcludingGit(loadedDirectoryPath, out totalFiles, out totalDirs);
int totalCount = totalFiles + totalDirs;

替代方案:LINQ过滤(适合简单场景)

如果你不想写递归方法,也可以用LINQ过滤所有路径,但这种方法会先遍历所有目录(包括.git)再过滤,效率稍低:

// 过滤所有不包含.git目录的文件
var filteredFiles = Directory.GetFiles(loadedDirectoryPath, "*", SearchOption.AllDirectories)
                             .Where(file => !file.Split(Path.DirectorySeparatorChar).Contains(".git"));

// 过滤所有不是.git的目录
var filteredDirs = Directory.GetDirectories(loadedDirectoryPath, "*", SearchOption.AllDirectories)
                            .Where(dir => Path.GetFileName(dir) != ".git");

int totalCount = filteredFiles.Count() + filteredDirs.Count();

总结

手动递归的方法更高效,因为它从根源上跳过了.git目录,避免了不必要的遍历。而LINQ过滤适合快速实现,但在大型仓库中可能会有性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:32:33