Как использовать DirectoryInfo.GetFiles и остановить его после нахождения первого совпадения? - PullRequest
4 голосов
/ 03 февраля 2012

Нужен поиск в каталоге / подкаталогах, чтобы найти файл, предпочел бы, чтобы он остановился, как только он его найдет.

Является ли эта функция встроенной в DirectoryInfo.GetFiles, которую мне не хватает, или долженЯ использую что-то еще (самореализованный рекурсивный поиск)?

Ответы [ 3 ]

13 голосов
/ 03 февраля 2012

Используйте 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)

4 голосов
/ 03 февраля 2012

Лучший метод для использования до .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;
    }
0 голосов
/ 03 февраля 2012

Вы пробовали DirectoryInfo.GetFiles ([Ваш шаблон], SearchOption.AllDirectories) .First ();

...