Robin Weichselbraun 37c33f3e15 initial commit
2025-05-09 14:26:16 +02:00

119 lines
4.0 KiB
C#

using System.Security.Cryptography;
namespace RedundancyFinder
{
public class Finder
{
List<Task> tasks = new List<Task>();
Dictionary<object, Redundancy> redundancies = new Dictionary<object, Redundancy>();
public Dictionary<object, Redundancy> Redundancies { get => redundancies; }
string[] extensions;
public void FindRedundancies(string[] paths, string[] extensions)
{
this.extensions = extensions;
foreach (var path in paths)
{
if (Directory.Exists(path))
{
ProcessDirectory(path);
}
else if (File.Exists(path))
{
ProcessFile(path);
}
}
// Wait for all tasks to complete
Task.WaitAll(tasks.ToArray());
foreach (var redundancy in redundancies.Values.ToList())
{
if (redundancy.Paths.Count == 1)
{
redundancies.Remove(redundancy.Hash);
}
}
}
private void ProcessDirectory(string directoryPath)
{
try
{
// Process files in the current directory
foreach (var file in Directory.GetFiles(directoryPath))
{
ProcessFile(file);
}
// Recursively process subdirectories
foreach (var subDirectory in Directory.GetDirectories(directoryPath))
{
try
{
ProcessDirectory(subDirectory);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"Access denied to directory: {subDirectory}. Skipping. Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while processing directory: {subDirectory}. Error: {ex.Message}");
}
}
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"Access denied to directory: {directoryPath}. Skipping. Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while processing directory: {directoryPath}. Error: {ex.Message}");
}
}
private void ProcessFile(string filePath)
{
if (!extensions.Contains(Path.GetExtension(filePath)))
{
return;
}
Task task = new(() =>
{
Console.WriteLine($"Processing file: {filePath}");
try
{
var fileHash = ComputeFileHash(filePath);
if (!redundancies.ContainsKey(fileHash))
{
long fileSize = new FileInfo(filePath).Length;
redundancies.Add(fileHash, new Redundancy() { Hash = fileHash, FileSize = fileSize });
}
redundancies[fileHash].Paths.Add(filePath);
}
catch (Exception ex)
{
Console.WriteLine($"Error processing file {filePath}: {ex.Message}");
}
});
task.Start();
tasks.Add(task);
}
private string ComputeFileHash(string filePath)
{
using var sha256 = SHA256.Create();
using var stream = File.OpenRead(filePath);
var hash = sha256.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
}