В чем разница между 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


16

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

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


6
В этом очень старом вопросе задавались вопросы о том, какие различия существовали помимо аспекта Arrayпротив Enumerable. Ваш ответ является общим для всех таких ситуаций, но не отвечает на заданный вопрос.
— Асигор

2
Дело в том, что EnumerateFiles позволяет вам в некоторых случаях быстрее получать доступ к данным.
— Скотт

16
Дело в том, что это очень полезно в качестве комментария, но не отвечает на вопрос. Есть различие.
— DJV
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.