需要一点调整的此实现要快5到10倍。
static List<Info> RecursiveScan2(string directory) { IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); WIN32_FIND_DATAW findData; IntPtr findHandle = INVALID_HANDLE_VALUE; var info = new List<Info>(); try { findHandle = FindFirstFileW(directory + @"*", out findData); if (findHandle != INVALID_HANDLE_VALUE) { do { if (findData.cFileName == "." || findData.cFileName == "..") continue; string fullpath = directory + (directory.EndsWith("\") ? "" : "\") + findData.cFileName; bool isDir = false; if ((findData.dwFileAttributes & FileAttributes.Directory) != 0) { isDir = true; info.AddRange(RecursiveScan2(fullpath)); } info.Add(new Info() { CreatedDate = findData.ftCreationTime.ToDateTime(), ModifiedDate = findData.ftLastWriteTime.ToDateTime(), IsDirectory = isDir, Path = fullpath }); } while (FindNextFile(findHandle, out findData)); } } finally { if (findHandle != INVALID_HANDLE_VALUE) FindClose(findHandle); } return info; }扩展方法:
public static class FILETIMEExtensions { public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME filetime ) { long highBits = filetime.dwHighDateTime; highBits = highBits << 32; return DateTime.FromFileTimeUtc(highBits + (long)filetime.dwLowDateTime); } }互操作性定义为:
[Dllimport("kernel32.dll", CharSet = CharSet.Unipre, SetLastError = true)] public static extern IntPtr FindFirstFileW(string lpFileName, out WIN32_FIND_DATAW lpFindFileData); [Dllimport("kernel32.dll", CharSet = CharSet.Unipre)] public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATAW lpFindFileData); [Dllimport("kernel32.dll")] public static extern bool FindClose(IntPtr hFindFile); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unipre)] public struct WIN32_FIND_DATAW { public FileAttributes dwFileAttributes; internal System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; internal System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; public int nFileSizeHigh; public int nFileSizeLow; public int dwReserved0; public int dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName; }


