使用C#(。NET 2.0),检索网络目录中文件列表的最佳方法是什么,优先选择按上次写入时间排序,还是根据上次写入时间排除返回值?
我目前正在使用DirectoryInfo实例的GetFiles方法返回一个列表。我遇到的目录可以包含超过6,000个文件,只需要获取FileInfo数组就需要大约25秒。
WMI无法运行,我看不到任何其他以.NET为中心的东西,这对于这种情况会有所帮助。我错过了什么吗?有没有比使用GetFiles更好的解决方案?
谢谢。
答案 0 :(得分:7)
<强>更新强>
我刚刚注意到这个旧的答案,对于.net 4.0以及后来有一个System.IO.EnumerateFiles
方法可以为你做这个,对于.net 4.0之前的所有内容,请继续阅读。
.Net 3.5&amp;早些时候
我和Stefan在一起,遇到了这个确切的问题,并推出了我自己的枚举器,用+ 100k文件迭代文件夹。
此类包含了使用FindFirstFile和FindNextFile所需的所有API特定内容。
希望这有帮助,
internal class APIWrapper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal sealed class FILETIME
{
public int Low;
public int High;
public Int64 ToInt64()
{
Int64 h = High;
h = h << 32;
return h + Low;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal sealed class FindData
{
public int fileAttributes;
public FILETIME CreationTime;
public FILETIME LastAccessTime;
public FILETIME LastWriteTime;
public int FileSizeHigh;
public int FileSizeLow;
public int dwReserved0;
public int dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public String fileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public String alternateFileName;
}
internal sealed class SafeFindHandle : Microsoft.Win32.SafeHandles.SafeHandleMinusOneIsInvalid
{
/// <summary>
/// Constructor
/// </summary>
public SafeFindHandle()
: base(true)
{
}
/// <summary>
/// Release the find handle
/// </summary>
/// <returns>true if the handle was released</returns>
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return SafeNativeMethods.FindClose(handle);
}
}
internal enum SearchOptions
{
NameMatch,
LimitToDirectories,
LimitToDevices
}
[SecurityPermissionAttribute(SecurityAction.Assert, UnmanagedCode = true)]
internal static class SafeNativeMethods
{
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] FindData findFileData);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern SafeFindHandle FindFirstFileEx(
String fileName, //__in LPCTSTR lpFileName,
[In] int infoLevel, //__in FINDEX_INFO_LEVELS fInfoLevelId,
[In, Out] FindData findFileData, //__out LPVOID lpFindFileData,
[In, Out] SearchOptions SerchOps, //__in FINDEX_SEARCH_OPS fSearchOp,
[In] int SearchFilter, //__reserved LPVOID lpSearchFilter,
[In] int AdditionalFlags); //__in DWORD dwAdditionalFlags
[DllImport("kernel32", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FindNextFile(SafeFindHandle hFindFile, [In, Out] FindData lpFindFileData);
[DllImport("kernel32", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FindClose(IntPtr hFindFile);
}
}
答案 1 :(得分:2)
不是FileInfo实例的排序规则是问题,而是访问上次写入时间时执行的API调用。
要获得明显更快的响应,您必须自己调用Win32 API函数FindFirstFile和FindNextFile。