private static IEnumerable <string> EnumerateFilesCore(string path, string searchPattern, SearchOption searchOption) { var queue = new Queue <string>(); queue.Enqueue(path); while (queue.Count > 0) { path = queue.Dequeue(); if (searchOption.HasFlag(SearchOption.Recursive)) { try { var directoryNames = Directory.EnumerateDirectories(path, "*", global::System.IO.SearchOption.TopDirectoryOnly); if (searchOption.HasFlag(SearchOption.UseSystemExclusions)) { directoryNames = directoryNames.Except(IgnoredDirectories, StringComparer.OrdinalIgnoreCase); } if (searchOption.HasFlag(SearchOption.Sort)) { //The results are already sorted (if using NTFS) //The underlying API is https://docs.microsoft.com/en-gb/windows/win32/api/fileapi/nf-fileapi-findnextfilea //.NET doesn't specify any order though so here we are.. directoryNames = directoryNames.OrderBy(); } queue.EnqueueRange(directoryNames); } catch { continue; } } var fileNames = new List <string>(); try { fileNames.AddRange( Directory.EnumerateFiles(path, searchPattern, global::System.IO.SearchOption.TopDirectoryOnly) ); if (searchOption.HasFlag(SearchOption.Sort)) { //The results are already sorted (if using NTFS) //The underlying API is https://docs.microsoft.com/en-gb/windows/win32/api/fileapi/nf-fileapi-findnextfilea //.NET doesn't specify any order though so here we are.. fileNames.Sort(); } } catch { continue; } foreach (var fileName in fileNames) { yield return(fileName); } } }
private static IEnumerable <string> EnumerateFilesCore(string path, string searchPattern, SearchOption searchOption) { var stack = new Stack <string>(); stack.Push(path); while (stack.Count > 0) { path = stack.Pop(); if (searchOption.HasFlag(SearchOption.Recursive)) { try { if (searchOption.HasFlag(SearchOption.UseSystemExclusions)) { stack.PushRange( Directory.EnumerateDirectories(path, "*", global::System.IO.SearchOption.TopDirectoryOnly).Except(IgnoredDirectories, StringComparer.OrdinalIgnoreCase) ); } else { stack.PushRange( Directory.EnumerateDirectories(path, "*", global::System.IO.SearchOption.TopDirectoryOnly) ); } } catch { continue; } } var fileNames = new List <string>(); try { fileNames.AddRange( Directory.EnumerateFiles(path, searchPattern, global::System.IO.SearchOption.TopDirectoryOnly) ); } catch { continue; } foreach (var fileName in fileNames) { yield return(fileName); } } }
public static IEnumerable <string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) { if (searchOption.HasFlag(SearchOption.UseSystemCache)) { //TODO: Warning: Buffering a potentially large sequence. return(Store.GetOrAdd(path, searchPattern, searchOption, () => EnumerateFilesCore(path, searchPattern, searchOption).ToArray())); } return(EnumerateFilesCore(path, searchPattern, searchOption)); }
/// <summary>Gets the directories contained in a directory.</summary> /// <param name="source">The source object.</param> /// <param name="searchPattern">The search pattern to use.</param> /// <param name="options">The search options.</param> /// <remarks> /// This method is similar to <see cref="O:Directory.EnumerateDirectories"/> except security exceptions are silently ignored allowing /// the retrieval to ignore directories that normally could not be processed. /// </remarks> /// <returns>The list of directories.</returns> public static IEnumerable <DirectoryInfo> SafeEnumerateDirectories(this DirectoryInfo source, string searchPattern, SearchOption options) { if (!source.Exists) { yield break; } if (String.IsNullOrEmpty(searchPattern)) { searchPattern = "*"; } //Push the root onto the stack var stack = new Stack <DirectoryInfo>(); stack.Push(source); bool includeChildren = options.HasFlag(SearchOption.AllDirectories); //Until we run out of directories (or we don't want all of them) do { //Pop the next directory var current = stack.Pop(); //Get the child directories if possible var children = TryEnumerateDirectories(current, searchPattern); if (children != null) { //For each child directory push it onto the stack and return it - we're ass foreach (var child in children) { if (includeChildren) { stack.Push(child); } yield return(child); } ; } ; } while (stack.Any()); }
/// <summary>Gets the files contained in a directory.</summary> /// <param name="source">The source object.</param> /// <param name="searchPattern">The search pattern to use.</param> /// <param name="options">The search options.</param> /// <remarks> /// This method is similar to <see cref="O:Directory.EnumerateFiles"/> except security exceptions are silently ignored allowing /// the retrieval to ignore directories that normally could not be processed. /// </remarks> /// <returns>The list of files.</returns> public static IEnumerable <FileInfo> SafeEnumerateFiles(this DirectoryInfo source, string searchPattern, SearchOption options) { if (!source.Exists) { yield break; } if (String.IsNullOrEmpty(searchPattern)) { searchPattern = "*.*"; } //Enumerate the root files first var children = TryEnumerateFiles(source, searchPattern); if (children != null) { foreach (var child in children) { yield return(child); } } ; //If we want all directories then enumerate the children if (options.HasFlag(SearchOption.AllDirectories)) { foreach (var dir in SafeEnumerateDirectories(source, null, options)) { children = TryEnumerateFiles(dir, searchPattern); if (children != null) { foreach (var child in children) { yield return(child); } } ; } ; } ; }
public static IEnumerable <string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) { if (searchOption.HasFlag(SearchOption.UseSystemCache)) { var paths = default(Lazy <IEnumerable <string> >); if (Store.TryGetValue(path, searchPattern, searchOption, out paths)) { return(paths.Value); } Store.Add( path, searchPattern, searchOption, new Lazy <IEnumerable <string> >( //TODO: Warning: Buffering a potentially large sequence. () => EnumerateFilesCore(path, searchPattern, searchOption).ToArray() ) ); //Second iteration will always hit cache. return(EnumerateFiles(path, searchPattern, searchOption)); } return(EnumerateFilesCore(path, searchPattern, searchOption)); }
public static IEnumerable <FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth) { var searchQueue = new Queue <DirectoryInfo>(); searchQueue.Enqueue(di); while (searchQueue.Count > 0) { var cdi = searchQueue.Dequeue(); IEnumerable <string> cdiFiles = null; if (returnOpt.HasFlag(ReturnOptions.ReturnFiles)) { try { cdiFiles = Directory.EnumerateFiles(cdi.FullName, filePattern, SearchOption.TopDirectoryOnly); } catch (Exception) { } if (cdiFiles != null) { var cfis = new ConcurrentBag <FileInfo>(); cdiFiles.AsParallel() .ForAll(f => { try { cfis.Add(new FileInfo(f)); } catch (Exception) { } }); foreach (var fi in cfis) { yield return(fi); } } } if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt.HasFlag(SearchOption.AllDirectories))) // skip if file enumeration failed { IEnumerable <string> cdiDirs = null; try { cdiDirs = Directory.EnumerateDirectories(cdi.FullName, dirPattern, SearchOption.TopDirectoryOnly); } catch (Exception) { } if (cdiDirs != null) { var cdis = new ConcurrentBag <DirectoryInfo>(); cdiDirs.AsParallel() .ForAll(d => { try { cdis.Add(new DirectoryInfo(d)); } catch (Exception) { } }); foreach (var rdi in cdis) { if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories)) { yield return(rdi); } if (searchOpt == SearchOption.AllDirectories) { searchQueue.Enqueue(rdi); } } } } } }