В чем разница между Directory.EnumerateFiles и Directory.GetFiles?

146

В чем разница между Directory.EnumerateFilesпротив GetFiles?

Очевидно, что один возвращает массив, а другой возвращает Enumerable.

Что-нибудь еще?

Дарт Вейдер
источник

Ответы:

173

Из документов :

Методы EnumerateFiles и GetFiles отличаются следующим образом: когда вы используете EnumerateFiles, вы можете начать перечисление коллекции имен до того, как будет возвращена вся коллекция; когда вы используете GetFiles, вы должны подождать, пока весь массив имен будет возвращен, прежде чем вы сможете получить доступ к массиву. Поэтому, когда вы работаете со многими файлами и каталогами, EnumerateFiles может быть более эффективным.

Таким образом, в основном, EnumerateFilesвозвращает a, IEnumerableкоторый может быть несколько лениво оценен, тогда как GetFilesвозвращает a, string[]который должен быть полностью заполнен, прежде чем он сможет вернуться.

Даниэль ДиПаоло
источник
5
Ленивая оценка не может быть полностью бесплатной - например, если вы в конце вернете ее обратно в массив (я это видел!). Ленивый эффективен, когда «yagni» - все: вам не понадобятся все элементы, и просто перестаньте выполнять итерации после нескольких.
Томаш Гандор
5
Ленивое перечисление также интересно, если вы собираетесь перечислять настолько большую коллекцию, что сборка всей коллекции первой в памяти является слишком тяжелой. Вы можете просто обрабатывать предметы по мере их поступления и забывать их.
Стефан Гурихон
1
@TomaszGandor: или когда нет необходимости хранить все имена файлов, например, просто переименовывая файлы.
Себастьян Мах
Я посмотрел на источники и обнаружил, что оба метода используют внутренние FileSystemEnumerableFactory.CreateFileInfoIterator(). Но EnumerateFiles()возвращает этот итератор напрямую, пока GetFiles()строит Listиз него лишние и вызывает ToArray(). Итак, если вы заботитесь о скорости, имеет смысл использовать EnumerateFiles()и иметь дело с итератором самостоятельно.
C0DEF52
32

EnumerateFilesвозвращает, IEnumerable<string>и это подразумевает отложенное выполнение. Это доступно только в Fx4 и выше.

Хенк Холтерман
источник
2
что значит Fx4?
Мин Нгуен,
3
.net FrameWork 4
Хенк
11
Это необычное имя для .NET 4.0
Snak
16

При использовании EnumerateFiles вся скорость теряется, если вы затем используете .Last. Это имеет смысл, конечно, потому что, чтобы добраться до последнего файла, ему нужно будет перечислить все файлы, а затем взять последний.

Тем не менее, использование .Firstили .FirstOrDefaultстановится очень быстрым, потому что он просто захватывает первый элемент и движется дальше.

Skotte
источник
6
В этом очень старом вопросе задавались вопросы о том, какие различия существовали помимо аспекта Arrayпротив Enumerable. Ваш ответ является общим для всех таких ситуаций, но не отвечает на заданный вопрос.
Асигор
2
Дело в том, что EnumerateFiles позволяет вам в некоторых случаях быстрее получать доступ к данным.
Скотт
16
Дело в том, что это очень полезно в качестве комментария, но не отвечает на вопрос. Есть различие.
DJV