Страницы

Поиск по вопросам

среда, 12 февраля 2020 г.

Поиск файлов в директориях

#c_sharp


Необходимо найти все файлы на диске. Есть такой код:                 

System.IO.DirectoryInfo number = new System.IO.DirectoryInfo(@"D:\");
int count = number.GetFiles().Length;


Ищет, но не ищет во всех папках. Пробовал так:            

System.IO.DirectoryInfo number = new System.IO.DirectoryInfo(@"D:\");
int count = number.GetFiles(".", SearchOption.AllDirectories).Length;

    


Ответы

Ответ 1



SearchOption.AllDirectories будет ронять весь поиск, если к одному из подкаталогов нет доступа. А учитывая, что ты передаёшь корень диска, там гарантированно попадётся System Volume Information и поиск упадёт. В остальном код работоспособный. Чтобы правильно обработать каталоги, к которым нет доступа, надо вместо передачи этого флага написать рекурсивную функцию, которая будет сама перебирать каталоги и игнорировать (или каким-либо ещё образом обрабатывать) исключения ошибки доступа. PS: https://ru.stackoverflow.com/a/419435/178988 http://bbs.vbstreets.ru/viewtopic.php?f=2&t=44440 http://www.cyberforum.ru/csharp-beginners/thread957151.html

Ответ 2



Раньше пробовала реализовать рекурсивный поиск в папке; может быть, кусочек моего кода Вам пригодится. private string directoryPath = @"D:\Папка"; /* Обработчик нажатия на кнопку "Сканировать". */ private void btnScan_Click(object sender, EventArgs e) { string mask = "*.sln"; // например, можно любую другую DirectoryInfo root = new DirectoryInfo(directoryPath); try { // Ищем файлы в корневой директории. getFiles(root); // Рекурсивный поиск по поддиректориям. getChildDirectories(root); } catch (Exception ex) { // ... } } private void getChildDirectories(DirectoryInfo rootDirectory) { foreach (DirectoryInfo directory in rootDirectory.GetDirectories()) { try { getFiles(directory); getChildDirectories(directory); } catch (Exception ex) { // ... } } } private void getFiles(DirectoryInfo directory) { var files = Directory.EnumerateFiles(directory.FullName, mask, SearchOption.TopDirectoryOnly); foreach (var file in files) { // делаешь что-то хорошее с каждым найденным файлом. } }

Ответ 3



Для целей поиска файлов и каталогов по различным критериям можно использовать следующую библиотеку: https://github.com/VladPVS/FastSearchLibrary/releases Краткий пример использования библиотеки для поиска файлов приведен ниже. using FastSearchLibrary; using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Threading; namespace SearchTest { class Program { private static object locker = new object(); static void Main(string[] args) { // Методы с окончанием Fast используют несколько потоков, что ускоряет операцию поиска, но увеличивает нагрузку на процессор. // Методы с окончанием Async не блокируют вызывающий поток, который продолжает выполняться далее. // Использование статических методов FileSearcher: var list = FileSearcher.GetFiles(@"C:\Users", (f) => f.Name.Contains("SomeFile")); var task1 = FileSearcher.GetFilesFastAsync(@"C:\Users", "*.txt"); var task2 = FileSearcher.GetFilesFastAsync(@"C:\", (f) => f.LastAccessTimeUtc >= new DateTime(2018, 3, 1)); List resultFiles1 = FileSearcher.GetFilesFast(@"C:\", (f) => f.Name.Contains("SomePattern")); List resultFiles2 = FileSearcher.GetFilesFast(@"C:\", (f) => f.CreationTime > new DateTime(2018, 1, 10)); List resultFiles3 = FileSearcher.GetFilesFast(@"C:\", (f) => { return (f.Extension == ".mp3") && (f.Length > 10485760) && (f.CreationTime > new DateTime(2018, 1, 10)); }); // Использование экземпляра класса FileSearcher позволяет получать результаты по мере их нахождения, // а также останавливать поиск, не дожидаясь его завершения: CancellationTokenSource tokenSource = new CancellationTokenSource(); FileSearcher searcher = new FileSearcher(@"C:\", (f) => Regex.IsMatch(f.Name, @".*Imagine[\S_]Dragons.*.mp3$"), tokenSource); List files = new List(); searcher.FilesFound += (sender, arg) => { lock (locker) { arg.Files.ForEach((f) => { files.Add(f); Console.WriteLine($"File location: {f.FullName}, \nCreation.Time: {f.CreationTime}"); }); if (files.Count >= 10) searcher.StopSearch(); } }; searcher.SearchCompleted += (sender, arg) => { if (arg.IsCanceled) Console.WriteLine("Search stopped."); else Console.WriteLine("Search completed."); Console.WriteLine($"Quantity of files: {files.Count}"); }; var task = searcher.StartSearchAsync(); task.Wait(); Console.ReadLine(); } } } Аналогично возможно совершать поиск каталогов, но уже с использованием класса DirectorySearcher.

Комментариев нет:

Отправить комментарий