如何使用DirectoryInfo.GetFiles并在找到第一个匹配后停止?

时间:2012-02-02 22:08:14

标签: c# getfiles file-search

需要搜索目录/子目录以查找文件,一旦找到文件就更愿意停止。

这是我缺少的DirectoryInfo.GetFiles内置的功能,还是我应该使用其他东西(自我实现的递归搜索)?

3 个答案:

答案 0 :(得分:13)

使用DirectoryInfo.EnumerateFiles()而不是懒惰地返回文件(而不是GetFiles将完整文件列表首先放入内存中) - 您可以添加FirstOrDefault()来实现您想要的效果:

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

来自MSDN:

  

EnumerateFiles和GetFiles方法的区别如下:当你   使用EnumerateFiles,您可以开始枚举集合   返回整个集合之前的FileInfo对象;当你使用   GetFiles,你必须等待整个FileInfo对象数组   在您可以访问该数组之前返回。因此,当你是   使用许多文件和目录,EnumerateFiles可以更多   高效。

DirectoryInfo.EnumerateFiles需要.NET 4.0)

答案 1 :(得分:4)

用于.NET 4.0之前的最佳方法,使用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);
    }

需要此结构

    //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;
    }

答案 2 :(得分:0)

您是否尝试过DirectoryInfo.GetFiles([Your Pattern],SearchOption.AllDirectories).First();