public async Task <IReadOnlyCollection <FileData> > Find(IReadOnlyCollection <SearchPath> searchPaths, IInclusionPredicate <FileData> inclusionPredicate, CancellationToken cancellationToken) { var fileSearchResults = new List <Task <IReadOnlyCollection <FileData> > >(); foreach (var physicalDrivePartitions in Drives.Get().GroupBy(drive => drive.PhysicalDriveNumber)) //Split the work by physical drives { var physicalDrivePaths = searchPaths.Where(searchPath => physicalDrivePartitions.Any(driveInfo => driveInfo.Name == new DirectoryInfo(searchPath.Path).Root.FullName)).ToArray(); if (physicalDrivePaths.Length == 0) { continue; } fileSearchResults.Add(Task.Run(() => FindFiles(physicalDrivePaths, inclusionPredicate, cancellationToken), cancellationToken)); } var searchResults = new List <FileData>(); foreach (var task in fileSearchResults) { searchResults.AddRange(await task); } return(searchResults); }
private IReadOnlyCollection <FileData> FindFiles(IEnumerable <SearchPath> searchPaths, IInclusionPredicate <FileData> inclusionPredicate, CancellationToken cancellationToken) { var foundFiles = new List <FileData>(); var searchPathsList = searchPaths.ToList(); var includePaths = GetPaths(searchPathsList, InclusionType.Include); var excludePaths = GetPaths(searchPathsList, InclusionType.Exclude); try { foreach (var path in includePaths) { cancellationToken.ThrowIfCancellationRequested(); foreach (var foundPath in FindPathFiles(path, excludePaths, foundFiles.Count, inclusionPredicate, cancellationToken)) { if (inclusionPredicate.IsIncluded(foundPath)) { foundFiles.Add(foundPath); } } } } catch (OperationCanceledException) { throw; } catch (DirectoryAccessFailedException ex) { OnFileSystemError(ex.DirectoryPath, ex.Message, ex); } catch (Exception ex) { OnFileSystemError("", ex.Message, ex); } return(foundFiles); }
private IEnumerable <FileData> FindPathFiles(string path, IReadOnlyCollection <string> excludePaths, int foundFilesCount, IInclusionPredicate <FileData> inclusionPredicate, CancellationToken cancellationToken) { using var directoryEnumerator = new DirectoryEnumeration(path).GetEnumerator(); var moreItems = false; do { FileData fileData; try { if (!(moreItems = directoryEnumerator.MoveNext())) { continue; } fileData = directoryEnumerator.Current; if (fileData == null) { continue; } } catch (FileSystemException ex) { OnFileSystemError(ex.FileFullName, ex.Message, ex); continue; } catch (Exception ex) { OnFileSystemError(path, ex.Message, ex); continue; } cancellationToken.ThrowIfCancellationRequested(); if (!inclusionPredicate.IsIncluded(fileData)) { continue; } var fileDataFullName = fileData.FullName; if (!fileData.Attributes.IsDirectory) { FilesSearchProgress?.Invoke(this, new FilesSearchProgressEventArgs(fileDataFullName, false, foundFilesCount++)); yield return(fileData); continue; } if (excludePaths.Any(excludePath => fileDataFullName.StartsWith(excludePath, StringComparison.OrdinalIgnoreCase))) { continue; } FilesSearchProgress?.Invoke(this, new FilesSearchProgressEventArgs(fileDataFullName, true, foundFilesCount)); foreach (var subDirFileData in FindPathFiles(fileDataFullName, excludePaths, foundFilesCount, inclusionPredicate, cancellationToken)) { FilesSearchProgress?.Invoke(this, new FilesSearchProgressEventArgs(fileDataFullName, false, foundFilesCount++)); yield return(subDirFileData); } } while (moreItems); }