using System; using System.Collections.Generic; using System.IO; using System.IO.Abstractions; using System.Linq; namespace Quadarax.Foundation.Core.IO { public class FileSearch { #region *** Private fields *** private IFileSystem _fs; #endregion #region *** Properties *** public string Path { get; } public bool IsDirctoryRecursive { get; } #endregion #region *** Constructors *** public FileSearch(IFileSystem fileSystemAbstraction, string initialPath, bool includeSubdirs = true) { _fs = fileSystemAbstraction ?? throw new ArgumentNullException(nameof(fileSystemAbstraction)); if (string.IsNullOrEmpty(initialPath)) throw new ArgumentNullException(nameof(initialPath)); if (!_fs.Directory.Exists(initialPath)) throw new FileNotFoundException($"Initial path '{initialPath}' doesn't exists."); Path = initialPath; IsDirctoryRecursive = includeSubdirs; } public FileSearch(string initialPath, bool includeSubdirs = true) : this(new System.IO.Abstractions.FileSystem(),initialPath, includeSubdirs) { } #endregion #region *** Public operations *** public string[] Search() { return Search(new[] {"*"}); } public string[] Search(IEnumerable includePatterns, FileSearchComparer? comparer = null) { return Search(includePatterns, new List(), comparer); } public string[] Search(IEnumerable includePatterns, IEnumerable excludePatterns, FileSearchComparer? comparer = null) { if (includePatterns == null) throw new ArgumentNullException(nameof(includePatterns)); if (excludePatterns == null) throw new ArgumentNullException(nameof(excludePatterns)); if (!includePatterns.Any()) includePatterns = new List(new[] {"*"}); comparer ??= new FileSearchComparer(includePatterns, excludePatterns); return SearchFiles(Path,comparer); } #endregion #region *** Private Operations *** private string[] SearchFiles(string initialDirPath, FileSearchComparer comparer) { var result = new List(); // iterate files foreach (var file in _fs.Directory.GetFiles(initialDirPath)) { // check if file match condition if (comparer.Match(file)) result.Add(file); } if (IsDirctoryRecursive) { // iterate sub-dirs foreach (var currentDir in _fs.Directory.GetDirectories(initialDirPath)) { // check if directory match condition if (comparer.Match(currentDir)) result.AddRange(SearchFiles(currentDir, comparer)); } } return result.ToArray(); } #endregion } }