Я пишу программу, которая должна искать каталог и все его подкаталоги для файлов с определенным расширением. Это будет использоваться как на локальном, так и на сетевом диске, поэтому производительность является проблемой.
Здесь рекурсивный метод, который я использую сейчас:
private void GetFileList(string fileSearchPattern, string rootFolderPath, List<FileInfo> files)
{
DirectoryInfo di = new DirectoryInfo(rootFolderPath);
FileInfo[] fiArr = di.GetFiles(fileSearchPattern, SearchOption.TopDirectoryOnly);
files.AddRange(fiArr);
DirectoryInfo[] diArr = di.GetDirectories();
foreach (DirectoryInfo info in diArr)
{
GetFileList(fileSearchPattern, info.FullName, files);
}
}
Я могу установить SearchOption в AllDirectories и не использовать рекурсивный метод, но в будущем мне захочется вставить код, чтобы уведомить пользователя о том, какая папка в настоящее время проверяется.
Пока я создаю список объектов FileInfo, все, что мне действительно волнует, это пути к файлам. У меня будет существующий список файлов, который я хочу сравнить с новым списком файлов, чтобы увидеть, какие файлы были добавлены или удалены. Есть ли более быстрый способ создания этого списка путей к файлу? Есть ли что-то, что я могу сделать, чтобы оптимизировать этот поиск файлов вокруг запросов к файлам на общем сетевом диске?
Обновление 1
Я попытался создать нерекурсивный метод, который делает то же самое, сначала обнаружив все вспомогательные каталоги, а затем итеративно сканируя каждый каталог для файлов. Здесь метод:
public static List<FileInfo> GetFileList(string fileSearchPattern, string rootFolderPath)
{
DirectoryInfo rootDir = new DirectoryInfo(rootFolderPath);
List<DirectoryInfo> dirList = new List<DirectoryInfo>(rootDir.GetDirectories("*", SearchOption.AllDirectories));
dirList.Add(rootDir);
List<FileInfo> fileList = new List<FileInfo>();
foreach (DirectoryInfo dir in dirList)
{
fileList.AddRange(dir.GetFiles(fileSearchPattern, SearchOption.TopDirectoryOnly));
}
return fileList;
}
Обновление 2
Хорошо, поэтому я запустил несколько тестов в локальной и удаленной папке, у которых есть много файлов (~ 1200). Вот методы, на которых я запускал тесты. Ниже приведены результаты.
- GetFileListA(). Нерекурсивное решение в приведенном выше обновлении. Я думаю, что это эквивалентно решению Джея.
- GetFileListB(): рекурсивный метод из исходного вопроса
- GetFileListC(). Получает все каталоги со статическим методом Directory.GetDirectories(). Затем получает все пути к файлу со статическим методом Directory.GetFiles(). Заполняет и возвращает список
- GetFileListD(): решение Марка Гравелла с использованием очереди и возвращает IEnumberable. Я заполнил список с результатом IEnumerable
- DirectoryInfo.GetFiles: никакого дополнительного метода не создано. Создал экземпляр DirectoryInfo из корневого каталога. Вызывается GetFiles с использованием SearchOption.AllDirectories
- Directory.GetFiles: дополнительный метод не создан. Вызывается статическим методом GetFiles каталога с использованием SearchOption.AllDirectories
Method Local Folder Remote Folder GetFileListA() 00:00.0781235 05:22.9000502 GetFileListB() 00:00.0624988 03:43.5425829 GetFileListC() 00:00.0624988 05:19.7282361 GetFileListD() 00:00.0468741 03:38.1208120 DirectoryInfo.GetFiles 00:00.0468741 03:45.4644210 Directory.GetFiles 00:00.0312494 03:48.0737459
.,.so выглядит как Марк самый быстрый.