How to use DirectoryInfo.GetFiles and have it stop

2019-02-18 08:47发布

Need to search the directory/sub-directories to find a file, would prefer it to stop once it has found one.

Is this a feature built into DirectoryInfo.GetFiles that I am missing, or should I be using something else (self-implemented recursive search)?

3条回答
贪生不怕死
2楼-- · 2019-02-18 09:13

Have you tried DirectoryInfo.GetFiles([Your Pattern], SearchOption.AllDirectories).First();

查看更多
太酷不给撩
3楼-- · 2019-02-18 09:14

Use DirectoryInfo.EnumerateFiles() instead which is lazily returning the files (as opposed to GetFiles which is bringing the full file list into memory first) - you can add FirstOrDefault() to achieve what you want:

var firstTextFile = new DirectoryInfo(someDirectory).EnumerateFiles("*.txt")
                                                    .FirstOrDefault();

From MSDN:

The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of FileInfo objects before the whole collection is returned; when you use GetFiles, you must wait for the whole array of FileInfo objects to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.

(DirectoryInfo.EnumerateFiles requires .NET 4.0)

查看更多
Animai°情兽
4楼-- · 2019-02-18 09:14

The best method to use for pre-.NET 4.0, use FindFirstFile()

    [DllImport("kernel32", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool FindClose(IntPtr hFindFile);

    public void findFile()
    {
        WIN32_FIND_DATA findData;
        var findHandle = FindFirstFile(@"\\?\" + directory + @"\*", out findData);
        FindClose(findHandle);
    }

Requires this struct

    //Struct layout required for FindFirstFile
    [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;
    }
查看更多
登录 后发表回答