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

C#应用中如何使用Win32 API递归获取含完整路径的目录与文件列表

C#使用Win32 API高速递归遍历目录实现

针对大文件量目录扫描场景,Win32 API相比.NET原生目录操作接口性能更优,可实现数千到上万级文件目录的快速遍历。

需求说明

现有基础实现仅能输出D盘根目录下的文件/文件夹名称,无完整路径,需改造为支持递归遍历所有子文件夹、子文件夹内的所有文件,同时输出完整路径。

依赖枚举与结构体定义

public enum FINDEX_SEARCH_OPS
{
    FindExSearchNameMatch = 0,
    FindExSearchLimitToDirectories = 1,
    FindExSearchLimitToDevices = 2
}

public enum FINDEX_INFO_LEVELS
{
    FindExInfoStandard = 0,
    FindExInfoBasic = 1
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct WIN32_FIND_DATA
{
    public uint dwFileAttributes;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
    public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
    public uint nFileSizeHigh;
    public uint nFileSizeLow;
    public uint dwReserved0;
    public uint dwReserved1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string cFileName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
    public string cAlternateFileName;
}

完整递归遍历实现代码

using System;
using System.Runtime.InteropServices;
using System.IO;

class Program
{
    // Kernal32.dll 文件操作相关导入
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr FindFirstFileEx(
        string lpFileName,
        FINDEX_INFO_LEVELS fInfoLevelId,
        out WIN32_FIND_DATA lpFindFileData,
        FINDEX_SEARCH_OPS fSearchOp,
        IntPtr lpSearchFilter,
        int dwAdditionalFlags);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);

    [DllImport("kernel32.dll")]
    static extern bool FindClose(IntPtr hFindFile);

    public const int FIND_FIRST_EX_CASE_SENSITIVE = 1;
    public const int FIND_FIRST_EX_LARGE_FETCH = 2;

    static void Main()
    {
        // 遍历起始路径,可自行修改
        string rootPath = @"D:\";
        ScanDirectory(rootPath);
        Console.ReadLine();
    }

    /// <summary>
    /// 递归扫描指定目录下的所有文件和子目录
    /// </summary>
    /// <param name="directoryPath">要扫描的目录完整路径</param>
    static void ScanDirectory(string directoryPath)
    {
        FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
        int additionalFlags = 0;
        // Vista及以上系统开启优化参数
        if (Environment.OSVersion.Version.Major >= 6)
        {
            findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
            // 大批量文件扫描可开启以下参数进一步提升性能
            additionalFlags = FIND_FIRST_EX_LARGE_FETCH;
        }

        string searchPattern = Path.Combine(directoryPath, "*.*");
        WIN32_FIND_DATA findData;

        IntPtr hFile = FindFirstFileEx(
            searchPattern,
            findInfoLevel,
            out findData,
            FINDEX_SEARCH_OPS.FindExSearchNameMatch,
            IntPtr.Zero,
            additionalFlags);

        if (hFile.ToInt32() != -1)
        {
            do
            {
                // 跳过.和..两个系统目录
                if (findData.cFileName == "." || findData.cFileName == "..")
                {
                    continue;
                }

                string fullPath = Path.Combine(directoryPath, findData.cFileName);
                Console.WriteLine("找到条目:{0},属性:{1}", fullPath, findData.dwFileAttributes);

                // 如果是目录,递归扫描
                if ((findData.dwFileAttributes & (uint)FileAttributes.Directory) != 0)
                {
                    try
                    {
                        ScanDirectory(fullPath);
                    }
                    catch (Exception ex)
                    {
                        // 可根据需要处理无权限访问等异常
                        Console.WriteLine("扫描目录{0}失败:{1}", fullPath, ex.Message);
                    }
                }

            } while (FindNextFile(hFile, out findData));

            FindClose(hFile);
        }
    }
}

功能说明

  • 自动跳过.和..系统默认目录,避免递归死循环
  • 遍历到目录时自动触发递归扫描子目录内容
  • 输出内容自动拼接完整路径,可直接对应到磁盘上的实际文件/目录位置
  • 加入了异常捕获逻辑,可处理无权限访问、系统保留目录等扫描异常场景
  • 支持开启FIND_FIRST_EX_LARGE_FETCH参数,进一步提升大批量文件场景下的扫描速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:39:04