protected IEnumerable <FileSystemFinderResult> Find(
            string directoryPath,
            SearchContext context,
            INotifyDirectoryChanged notifyDirectoryChanged)
        {
            IEnumerable <FileSystemFinderResult> results = FileSystemFinder.Find(
                directoryPath: directoryPath,
                nameFilter: Options.NameFilter,
                extensionFilter: Options.ExtensionFilter,
                directoryFilter: Options.DirectoryFilter,
                options: FinderOptions,
                progress: context.Progress,
                notifyDirectoryChanged: notifyDirectoryChanged,
                cancellationToken: context.CancellationToken);

            if (Options.FilePropertyFilter != null)
            {
                results = results.Where(Options.FilePropertyFilter.IsMatch);
            }

            return(results);
        }
Beispiel #2
0
        public static IEnumerable <FileSystemFinderResult> Find(
            string directoryPath,
            Filter nameFilter               = null,
            Filter extensionFilter          = null,
            Filter directoryFilter          = null,
            FileSystemFinderOptions options = null,
            IProgress <FileSystemFinderProgress> progress  = null,
            INotifyDirectoryChanged notifyDirectoryChanged = null,
            CancellationToken cancellationToken            = default)
        {
            if (options == null)
            {
                options = FileSystemFinderOptions.Default;
            }

            var enumerationOptions = new EnumerationOptions()
            {
                AttributesToSkip         = options.AttributesToSkip,
                IgnoreInaccessible       = options.IgnoreInaccessible,
                MatchCasing              = options.MatchCasing,
                MatchType                = options.MatchType,
                RecurseSubdirectories    = false,
                ReturnSpecialDirectories = options.ReturnSpecialDirectories
            };

            NamePartKind namePart          = nameFilter?.NamePart ?? NamePartKind.Name;
            NamePartKind directoryNamePart = directoryFilter?.NamePart ?? NamePartKind.Name;

            var            directories    = new Queue <string>();
            Queue <string> subDirectories = (options.RecurseSubdirectories) ? new Queue <string>() : null;

            string currentDirectory = null;

            if (notifyDirectoryChanged != null)
            {
                notifyDirectoryChanged.DirectoryChanged += (object sender, DirectoryChangedEventArgs e) => currentDirectory = e.NewName;
            }

            string dirPath = directoryPath;

            while (true)
            {
                progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory));

                if (options.SearchTarget != SearchTarget.Directories)
                {
                    IEnumerator <string> fi = null;

                    try
                    {
                        fi = (options.CanEnumerate)
                            ? Directory.EnumerateFiles(dirPath, "*", enumerationOptions).GetEnumerator()
                            : ((IEnumerable <string>)Directory.GetFiles(dirPath, "*", enumerationOptions)).GetEnumerator();
                    }
                    catch (Exception ex) when(IsWellKnownException(ex))
                    {
                        progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory, ex));
                    }

                    if (fi != null)
                    {
                        using (fi)
                        {
                            while (fi.MoveNext())
                            {
                                FileSystemFinderResult?result = MatchFile(fi.Current, nameFilter, extensionFilter, options, progress, namePart);

                                if (result != null)
                                {
                                    yield return(result.Value);
                                }

                                cancellationToken.ThrowIfCancellationRequested();
                            }
                        }
                    }
                }

                IEnumerator <string> di = null;

                try
                {
                    di = (options.CanEnumerate)
                        ? Directory.EnumerateDirectories(dirPath, "*", enumerationOptions).GetEnumerator()
                        : ((IEnumerable <string>)Directory.GetDirectories(dirPath, "*", enumerationOptions)).GetEnumerator();
                }
                catch (Exception ex) when(IsWellKnownException(ex))
                {
                    progress?.Report(new FileSystemFinderProgress(dirPath, ProgressKind.SearchedDirectory, ex));
                }

                if (di != null)
                {
                    using (di)
                    {
                        while (di.MoveNext())
                        {
                            currentDirectory = di.Current;

                            if (directoryFilter?.IsMatch(NamePart.FromDirectory(currentDirectory, directoryNamePart)) != false)
                            {
                                if (options.SearchTarget != SearchTarget.Files &&
                                    namePart != NamePartKind.Extension)
                                {
                                    FileSystemFinderResult?result = MatchDirectory(currentDirectory, nameFilter, options, progress);

                                    if (result != null)
                                    {
                                        yield return(result.Value);
                                    }
                                }

                                if (currentDirectory != null &&
                                    options.RecurseSubdirectories)
                                {
                                    subDirectories !.Enqueue(currentDirectory);
                                }
                            }

                            cancellationToken.ThrowIfCancellationRequested();
                        }
                    }

                    if (options.RecurseSubdirectories)
                    {
                        while (subDirectories !.Count > 0)
                        {
                            directories.Enqueue(subDirectories.Dequeue());
                        }
                    }
                }

                if (directories.Count > 0)
                {
                    dirPath = directories.Dequeue();
                }
                else
                {
                    break;
                }
            }
        }