Мне нужно подсчитать количество файлов в каталоге. Я мог бы получить имена всех файлов в каталоге с помощью System.IO.Directory.GetFiles() и взять длину этого массива, но это занимает слишком много времени для больших каталогов. Есть ли способ получить только счет без необходимости получать имена?





Я так не верю, нет - по крайней мере, не в ванильном .NET. Я подозреваю, что время занимает не фактическая выборка имен, а работа операционной системы по внутреннему каталогу. май - это вызов Win32, который вы можете сделать через P / Invoke.
Насколько велик каталог, который вы смотрите? В общем, по крайней мере, традиционно - не лучшая идея иметь более нескольких сотен файлов в каталоге. Файловые системы в целом улучшились, но я не знаю, каково текущее состояние NTFS и Fat32.
что вы имеете в виду под ванильным .NET?
@Pacerier: я имею в виду без вызовов функции Win32 P / Invoke.
До сих пор на большинстве языков, с которыми я сталкивался, вы можете получить эту информацию, только пройдя по папке и посчитав файлы. Я сомневаюсь, что есть вызов Windows API, чтобы получить только счет (но я могу быть удивлен!).
Преимущество метода: гибкость - вы можете отфильтровать некоторые типы файлов, пройти рекурсивно или игнорировать папки и т. д.
Если этот метод для вас медленный, возможно, вам стоит найти лучший метод, например, не создавать массив, заполненный информацией о каталоге (требуется время для его заполнения! Не говоря уже о стоимости памяти и времени сборки мусора), но с использованием итератора: немного больше работают (но как только вы получите функцию, она всегда рядом), но намного эффективнее.
Провел небольшой тест - написал ту же задачу на C++ / Qt и C++ / CLI:
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
int count = IO::Directory::GetFiles(L"c:\\windows\\system32")->Length;
QueryPerformanceCounter(&i2);
__int64 result = i2.QuadPart - i1.QuadPart;
Результат около 16.500.000
а также
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
intcount = QDir("c:/windows/system32").entryList(QDir::Files).count();
QueryPerformanceCounter(&i2);
__int64 result += i2.QuadPart - i1.QuadPart;
Результат около 2.100.000.000
Количество файлов 2125
Нет более быстрого пути. Независимо от того, что вы используете, все сводится к вызовам FindFirstFile и FindNextFile Win32.
Вы можете попробовать использовать что-то вроде это, но это, вероятно, займет столько же времени - но, возможно, с немного меньшим использованием памяти (= вероятно, того не стоит).
Действительно, сама файловая система не ведет счет. Чтобы найти счет, он должен пересчитать весь список, поэтому на это уходит столько же времени.