以下是我最终实现的超快解决方案.这里我使用的是WinAPI和函数FindFirstFile、FindNextFile.它允许避免枚举文件夹和stops right after detecting the first object in the Folder中的所有项目.此方法为~6(!!)比上面描述的要快几倍.在36毫秒内打250个电话!
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private 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;
}
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll")]
private static extern bool FindClose(IntPtr hFindFile);
public static bool CheckDirectoryEmpty_Fast(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(path);
}
if (Directory.Exists(path))
{
if (path.EndsWith(Path.DirectorySeparatorChar.ToString()))
path += "*";
else
path += Path.DirectorySeparatorChar + "*";
WIN32_FIND_DATA findData;
var findHandle = FindFirstFile(path, out findData);
if (findHandle != INVALID_HANDLE_VALUE)
{
try
{
bool empty = true;
do
{
if (findData.cFileName != "." && findData.cFileName != "..")
empty = false;
} while (empty && FindNextFile(findHandle, out findData));
return empty;
}
finally
{
FindClose(findHandle);
}
}
throw new Exception("Failed to get directory first file",
Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
}
throw new DirectoryNotFoundException();
}
我希望它能在将来对某些人有用.