void RecursiveSearch(DirectoryItem current) { try { foreach (string fullDirectoryName in Directory.GetDirectories(current.FullPath, DirectoryMask)) { var directory = DirectoryItem.FromFullPath(BaseDirectory, fullDirectoryName); foreach (IDirectoryFinderComparer comparer in comparer) { if (!comparer.DirectoryMatches(directory)) { directory = null; break; } } if (directory != null) { if (deepestFirst) { // recursive search in directory first RecursiveSearch(directory); } // then add items to list while (searchRunning) { lock (this) { if (directoryList.Count < MaximumDirectoriesQueued) { directoryList.Enqueue(directory); break; } } Thread.Sleep(1); } if (!deepestFirst) { // recursive search later RecursiveSearch(directory); } } } } catch (Exception ex) { Trace.TraceError("Cannot get directory listing for {0}.\n{1}", current, ex); } }
/// <summary> /// Finds all files that match the criteria specified at the FileMaskList. /// The FileMaskList may contain absolute and relative paths, filenames or masks and the "|r" recurse subdirectories switch. /// </summary> /// <param name="directoryMaskList">The mask to apply.</param> /// <param name="mainPath">main path to begin relative searches.</param> /// <param name="recursive">if set to <c>true</c> [recursive].</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">directoryMaskList.</exception> /// <exception cref="System.IO.DirectoryNotFoundException"></exception> /// <example> /// @"c:\somepath\*", @"/absolute/path/dir*", @"./sub/*", @"*|r", @"./somepath/file.ext|r". /// </example> public static ICollection <DirectoryItem> FindDirectories(IEnumerable <string> directoryMaskList, string mainPath = null, bool recursive = false) { if (directoryMaskList == null) { throw new ArgumentNullException("directoryMaskList"); } if (mainPath != null) { mainPath = Path.GetFullPath(mainPath); } var result = new List <DirectoryItem>(); foreach (string dir in directoryMaskList) { try { SearchOption searchOption = SearchOption.TopDirectoryOnly; string mask = dir; if (mask.EndsWith("|r") || mask.EndsWith(":r") || recursive) { mask = mask.Substring(0, mask.Length - 2); searchOption = SearchOption.AllDirectories; } string path = "."; if (!string.IsNullOrEmpty(mask)) { path = Path.GetDirectoryName(mask); mask = Path.GetFileName(mask); } if (string.IsNullOrEmpty(mask)) { mask = "*"; } string basePath = mainPath ?? Path.GetFullPath(path); path = Path.GetFullPath(Combine(basePath, path)); if (!Directory.Exists(path)) { continue; } foreach (string directory in Directory.GetDirectories(path, mask, searchOption)) { result.Add(DirectoryItem.FromFullPath(basePath, directory)); } if (string.IsNullOrEmpty(mask)) { var directory = DirectoryItem.FromFullPath(basePath, path); if (!result.Contains(directory)) { result.Add(directory); } } } catch (Exception ex) { throw new DirectoryNotFoundException(string.Format("Error while trying to resolve '{0}'.", dir), ex); } } return(result); }
/// <summary>Initializes a new instance of the <see cref="DirectoryItemEventArgs"/> class.</summary> /// <param name="dir">The dir.</param> public DirectoryItemEventArgs(DirectoryItem dir) => Directory = dir;
/// <summary> /// runs the current search. /// </summary> void SearchDirectories() { Thread.CurrentThread.Priority = ThreadPriority.Lowest; Thread.CurrentThread.IsBackground = true; var queue = new Queue <Task>(); DirectoriesSeen = 1; { var directoryWalkerList = new Stack <string>(); directoryWalkerList.Push(BaseDirectory); int directoriesDone = 0; while (directoryWalkerList.Count > 0) { if (exit) { break; } string currentDirectory = directoryWalkerList.Pop(); DirectoriesDone++; while (queue.Peek().IsCompleted) { queue.Dequeue(); } if (queue.Count > 0) { Task.WaitAny(queue.ToArray()); } queue.Enqueue(Task.Factory.StartNew(() => { SearchFiles(currentDirectory); if (exit) { return; } FoundDirectory?.Invoke(this, new DirectoryItemEventArgs(DirectoryItem.FromFullPath(BaseDirectory, currentDirectory))); })); directoriesDone++; try { foreach (string directory in Directory.GetDirectories(currentDirectory, DirectoryMask)) { if (exit) { break; } DirectoriesSeen++; directoryWalkerList.Push(FileSystem.Combine(BaseDirectory, directory)); } } catch (Exception ex) { Error?.Invoke(this, new ErrorEventArgs(ex)); } } } Task.WaitAll(queue.ToArray()); }