Если содержимое файла идентично, то криптографический хэш, по крайней мере, очень хорошо показывает равенство.Класс SHA256
был бы хорошим кандидатом здесь, хотя это, возможно, немного выше.Например:
static byte[] Sha256HashFile(string file)
{
using (SHA256 sha256 = SHA256.Create())
{
using (Stream input = File.OpenRead(file))
{
return sha256.ComputeHash(input);
}
}
}
Самый простой способ сравнить два возвращенных байтовых массива - это, вероятно, преобразовать их оба в строки, используя Convert.ToBase64
, а затем сравнить строки.Уродливо, но легко :) Вы также можете использовать Enumerable.SequenceEqual
:
byte[] hash1 = Sha256HashFile("file1.png");
byte[] hash2 = Sha256HashFile("file2.png");
bool same = hash1.SequenceEqual(hash2);
Если вы хотите сохранить хеши в виде набора или словаря, вы можете реализовать свой собственный IEqualityComparer<byte[]>
, ночестно говоря, было бы проще всего использовать строку base64.Например, при этом будут распечатаны дубликаты файлов:
var hashToNameMap = new Dictionary<string, string>();
foreach (string file in files)
{
byte[] hash = Sha256HashFile(file);
string base64 = Convert.ToBase64(hash);
string existingName;
if (hashToNameMap.TryGetValue(base64, out existingName))
{
Console.WriteLine("{0} is a duplicate of {1}", file, existingName);
}
else
{
hashToNameMap[base64] = file;
}
}
Несколько примечаний:
- Это не гарантировано , чтобы быть точным, ношансы получить столкновение очень малы, особенно если файлы также должны быть действительными изображениями.
- Это включает чтение всех из каждого файла - даже если естьнет других файлов с таким же размером (и, следовательно, нет возможных дубликатов).Это может или не может быть проблемой для вас.
- Даже если в есть несколько файлов одинакового размера, вам нужно только прочитать все из них, чтобы найти дубликаты ... вы можетеПотенциально читайте файлы и вычисляйте хэши по ходу работы, останавливаясь, как только вы обнаружите, что файлы разные.
То, как вы к этому подходите, зависит от того, является ли ваша цель абсолютной скоростью, простотой кода и т. дЭто также может зависеть от того, будет ли пул расти со временем - например, вы можете захотеть хэшировать файлы, как только вы получите два или более файлов одинакового размера, чтобы при добавлении другого файла того же размера вы моглихэш , и добавьте его, даже не перечитывая существующие данные.