使用 MD5 哈希的 IEqualityComparer<FileInfo>





5.00/5 (3投票s)
此代码片段使用 IEqualityComparer 比较两个给定的文件。
引言
此代码片段使用 IEqualityComparer
比较两个给定的文件。
比较过程如下:
- 使用 FileInfo 的相等运算符 (==) 尝试确定它们是否是 FileInfo 类的相同实例
- 如果其中一个对象为 null
,则它们不能代表相同的文件,因此返回 false
- 如果两个对象的的文件路径相同,则返回 true,因为文件必须相同
- 如果文件大小不同,则文件也不能相同,因此返回 false
- 最后,我们采用比较两个文件的 MD5 哈希值。
请记住,MD5 哈希是一种代价较高的操作,不适合比较大量文件或大型文件。 此处提供的代码最初打算在集成测试中使用。 如果需要比较大量文件(或非常大的文件),您可以使用自己的实现 - 您可以从阅读 此 Stack Overflow 讨论 开始。
背景
请记住,此实现会将文件内容读取到内存中以创建每个文件的 MD5。 如果您尝试比较非常大的文件,这可能会大大降低应用程序的速度。
代码
/// <summary>
/// An <see cref="IEqualityComparer{T}"/> for files using <see cref="FileInfo"/>
/// </summary>
public class FileMd5EqualityComparer : IEqualityComparer<FileInfo>
{
/// <summary>
/// See <see cref="IEqualityComparer{T}.Equals(T, T)"/>
/// </summary>
public bool Equals(FileInfo x, FileInfo y)
{
// Use basic comparison
if(x == y)
{
return true;
}
// if one of both parameters is null, they can't be
// the same - Except both are null, but this case is
// handled above.
if(x == null || y == null)
{
return false;
}
// If both file paths are the same, the
// files must be the same.
if(x.FullName == y.FullName)
{
return true;
}
// The files can't be equal if they don't
// have the same size
if(x.Length != y.Length)
{
return false;
}
// At last, compare the MD5 of the files.
var md5X = GetMd5(x.FullName);
var md5Y = GetMd5(y.FullName);
return md5X == md5Y;
}
/// <summary>
/// See <see cref="IEqualityComparer{T}.Equals(T, T)"/>
/// </summary>
public int GetHashCode(FileInfo obj)
{
return obj.GetHashCode();
}
/// <summary>
/// Returns the MD5 of the file at <paramref name="filePath"/>
/// as string
/// </summary>
private string GetMd5(string filePath)
{
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filePath))
{
return Encoding.Default.GetString(md5.ComputeHash(stream));
}
}
}
}
历史
2018-05-25 初始版本