2025-06-09 16:14:20 +01:00

83 lines
2.7 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
public class FileScanner
{
//all extensions and cuncurrent bag as a list wich works threw out multiple threads
private readonly string[] _extensions;
private readonly ConcurrentBag<string> _foundFiles = new ConcurrentBag<string>();
public FileScanner(string[] extensions)
{
_extensions = extensions.Select(e => e.ToLower()).ToArray();
}
//return a list of all coneckted drives
public async Task<List<string>> ScanAllDrivesAsync()
{
var drives = new List<string>();
foreach (var drive in DriveInfo.GetDrives())
{
if (!drive.IsReady) continue;
Console.WriteLine($"Scanning {drive.Name} ...");
string root = drive.RootDirectory.FullName;
drives.Add(root);
}
return drives.ToList();
}
//scan teh designated drive or folder
public async Task<List<string>> ScanDriveParallel(string rootPath)
{
//all sub direcktorys will be also added to this bag
var folderQueue = new ConcurrentQueue<string>();
folderQueue.Enqueue(rootPath);
//all aktive skanners are placed here
var folderWorkers = new List<Task>();
//keep max tasks at half teh amounts of cores
int maxWorkers = Environment.ProcessorCount/2;
for (int i = 0; i < maxWorkers; i++)
{
folderWorkers.Add(Task.Run(() =>
{
while (folderQueue.TryDequeue(out string currentPath))
{
try
{
// Check files
foreach (var file in Directory.GetFiles(currentPath))
{
if (_extensions.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase)))
{
//Console.WriteLine(file);
_foundFiles.Add(file);
}
}
// Enqueue subdirectories
foreach (var dir in Directory.GetDirectories(currentPath))
{
folderQueue.Enqueue(dir);
}
}
catch
{
// Skip inaccessible folders silently
}
}
}));
}
//wait till all tasks are done
Task.WaitAll(folderWorkers.ToArray());
//return the found paths as string
return _foundFiles.ToList();
}
}