【问题标题】:C# get file names and last write times for large directoriesC# 获取大目录的文件名和最后写入时间
【发布时间】:2009-11-16 10:29:35
【问题描述】:

使用 C# (.NET 2.0),在网络目录中检索文件列表的最佳方法是什么,优先按上次写入时间排序,或者根据上次写入时间排除返回?

我目前正在使用 DirectoryInfo 实例的 GetFiles 方法返回一个列表。我遇到的目录可以包含超过 6,000 个文件,仅获取 FileInfo 数组就需要将近 25 秒。

WMI 将不起作用,我看不到任何其他以 .NET 为中心的对这种情况有帮助的东西。我错过了什么吗?有没有比使用 GetFiles 更好的解决方案?

谢谢。

【问题讨论】:

    标签: c# .net file


    【解决方案1】:

    更新
    我刚刚注意到这个旧答案,对于 .net 4.0 和更高版本有一个 System.IO.EnumerateFiles 方法可以为您执行此操作,对于 .net 4.0 之前的所有内容,请继续阅读。

    .Net 3.5 及更早版本

    我和 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      问题不是 FileInfo 实例的排序,而是访问上次写入时间时执行的 API 调用。

      要获得明显更快的响应,您必须自己调用 Win32 API 函数 FindFirstFile 和 FindNextFile。

      【讨论】:

      • 我刚刚意识到我没有投票给你的答案,我早就应该这样做了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      相关资源
      最近更新 更多