nihil e6e259ed47 remove tasks
fixed ignoring hidden folders
2025-05-10 14:04:08 +02:00

126 lines
4.3 KiB
C#

using System.Security.Cryptography;
namespace RedundancyFinder
{
public class Finder
{
Dictionary<string, Redundancy> redundancies = new Dictionary<string, Redundancy>();
public Dictionary<string, Redundancy> Redundancies { get => redundancies; }
string[] extensions;
public event EventHandler<DirectoryErrorEventArgs>? DirectoryError;
public event EventHandler<FileErrorEventArgs>? FileError;
public event EventHandler<FileFoundEventArgs>? FileFound;
public event EventHandler<string>? TaskStarted;
public event EventHandler<ProcessingFileEventArgs>? ProcessingFile;
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);
}
}
}
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))
{
// Check if the directory is hidden and skip it if true
var attributes = File.GetAttributes(subDirectory);
if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
{
continue;
}
try
{
ProcessDirectory(subDirectory);
}
catch (Exception ex)
{
DirectoryError?.Invoke(this, new DirectoryErrorEventArgs() { Exception = ex, Path = subDirectory });
}
}
}
catch (Exception ex)
{
DirectoryError?.Invoke(this, new DirectoryErrorEventArgs() { Exception = ex, Path = directoryPath });
}
}
private void ProcessFile(string filePath)
{
if (!extensions.Contains(Path.GetExtension(filePath)))
{
return;
}
TaskStarted?.Invoke(this, filePath);
ProcessingFile?.Invoke(this, new ProcessingFileEventArgs() { Path = filePath });
try
{
var fileHash = ComputeFileHash(filePath);
if (fileHash == null)
{
return;
}
long fileSize = new FileInfo(filePath).Length;
lock (redundancies)
{
if (redundancies.ContainsKey(fileHash))
{
return;
}
if (!redundancies.ContainsKey(fileHash))
{
var redundancy = new Redundancy() { Hash = fileHash, FileSize = fileSize };
redundancies.Add(fileHash, redundancy);
}
redundancies[fileHash].Paths.Add(filePath);
}
FileFound?.Invoke(this, new FileFoundEventArgs(filePath, fileHash, fileSize));
}
catch (Exception ex)
{
FileError?.Invoke(this, new FileErrorEventArgs() { Exception = ex, Path = filePath });
}
}
private static 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();
}
}
}