82 lines
2.5 KiB
C#
82 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Aurora.Utils
|
|
{
|
|
public class FileSystemUtils
|
|
{
|
|
|
|
public FileSystemUtils()
|
|
{
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Asynchronousely recursively traverse a directory path.
|
|
/// </summary>
|
|
/// <param name="path">The path to the directory to traverse</param>
|
|
/// <param name="extensions">Comma separated list of file extensions to accept</param>
|
|
public static List<FileInfo> TraverseFoldersAsync(string path, string extensions)
|
|
{
|
|
string[] extensionList = extensions.Split(',');
|
|
|
|
ConcurrentBag<Task> tasks = new ConcurrentBag<Task>();
|
|
List<FileInfo> outFiles = new List<FileInfo>();
|
|
DirectoryInfo directoryInfo = new DirectoryInfo(path);
|
|
|
|
tasks.Add(Task.Run(() => Traverse(directoryInfo, tasks, outFiles, extensionList)));
|
|
|
|
Task waitingTask;
|
|
while (tasks.TryTake(out waitingTask))
|
|
{
|
|
waitingTask.Wait();
|
|
}
|
|
|
|
return outFiles;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Recursive method to capture children of a directory.
|
|
/// </summary>
|
|
/// <param name="dir">The directory to traverse</param>
|
|
/// <param name="tasks">The list of currently running tasks</param>
|
|
private static void Traverse(DirectoryInfo dir, ConcurrentBag<Task> tasks, List<FileInfo> outFiles, string[] extensions)
|
|
{
|
|
try
|
|
{
|
|
DirectoryInfo[] directoryInfos = dir.GetDirectories();
|
|
//Enque children
|
|
foreach (DirectoryInfo childInfo in directoryInfos)
|
|
{
|
|
tasks.Add(Task.Run(() => Traverse(childInfo, tasks, outFiles, extensions)));
|
|
}
|
|
|
|
//Collect files
|
|
foreach (FileInfo fileInfo in dir.GetFiles())
|
|
{
|
|
if (extensions.Any(e => e == fileInfo.Extension))
|
|
{
|
|
//Don't know if this lock is necessary
|
|
lock (outFiles)
|
|
{
|
|
outFiles.Add(fileInfo);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"{ex.GetType()} {ex.Message}\n{ex.StackTrace}");
|
|
ex = ex.InnerException;
|
|
}
|
|
}
|
|
|
|
}
|
|
} |