C# 如何使用.NET检查两个文件是否相等?
假设我有一个文件a.doc。C# 如何使用.NET检查两个文件是否相等?,c#,C#,假设我有一个文件a.doc。 然后我将其复制到b.doc并将其移动到另一个目录。 对我来说,它仍然是同一个文件。 但我如何确定它是正确的呢? 当我下载文件时,我有时会读到关于获取mda5或校验和的内容,但我不知道这是关于什么 有没有办法检查这些文件是否二进制相等?确实有。打开这两个文件,将它们作为字节数组读入,然后比较每个字节。如果它们相等,则文件相等。首先比较文件的大小,如果大小不同,则文件不同,如果大小相同,则只需比较文件内容。如果要100%确定文件中的确切字节相同,然后打开两个流并比较文件
然后我将其复制到b.doc并将其移动到另一个目录。
对我来说,它仍然是同一个文件。
但我如何确定它是正确的呢?
当我下载文件时,我有时会读到关于获取mda5或校验和的内容,但我不知道这是关于什么
有没有办法检查这些文件是否二进制相等?确实有。打开这两个文件,将它们作为字节数组读入,然后比较每个字节。如果它们相等,则文件相等。首先比较文件的大小,如果大小不同,则文件不同,如果大小相同,则只需比较文件内容。如果要100%确定文件中的确切字节相同,然后打开两个流并比较文件的每个字节是唯一的方法 如果您只是想非常确定(99.9999%?),我会计算每个文件的MD5哈希值,然后比较哈希值。签出System.Security.Cryptography.MD5CryptoServiceProvider 在我的测试中,如果文件通常是等效的,那么比较MD5哈希比比较文件的每个字节快三倍左右。
如果文件通常不同,那么逐字节比较会快得多,因为您不必读取整个文件,只要有一个字节不同,就可以停止读取 编辑:我最初是根据一个快速测试得出这个答案的,该测试逐字节读取每个文件,并逐字节比较它们。我错误地认为System.IO.FileStream的缓冲特性可以让我不用担心硬盘块大小和读取速度;事实并非如此。我重新测试了我的程序,该程序以4096字节的块读取每个文件,然后比较这些块——这种方法总体上比MD5稍快一些,即使文件完全相同,如果它们不同,当然也会快得多 我留下这个答案只是对FileStream类的一个轻微警告,因为我仍然认为它对于“如何计算.NET中文件的MD5”的答案有一定的价值。除此之外,这并不是满足最初要求的最佳方式 计算两个文件的MD5哈希的示例(现在已测试!):
使用(var reader1=new System.IO.FileStream(filepath1,System.IO.FileMode.Open,System.IO.FileAccess.Read))
{
使用(var reader2=new System.IO.FileStream(filepath2、System.IO.FileMode.Open、System.IO.FileAccess.Read))
{
字节[]hash1;
字节[]hash2;
使用(var md51=new System.Security.Cryptography.MD5CryptoServiceProvider())
{
md51.ComputeHash(reader1);
hash1=md51.Hash;
}
使用(var md52=new System.Security.Cryptography.MD5CryptoServiceProvider())
{
md52.ComputeHash(reader2);
hash2=md52.Hash;
}
int j=0;
对于(j=0;j
是否希望以编程方式执行此操作,否则这更适合在SuperUser.com上执行?是的,我正在创建一个小程序来删除重复项。虽然此代码“较短”,但肯定要比逐字节比较慢得多,而且通常更差。更不用说MD5是一个死哈希(从密码学的角度来说)。如果您只是想检查文件是否相等,我真的不会这样做。@silky:我怀疑这取决于文件的大小以及用例是否有更高的机会使它们相等,但是计算两个文件的MD5要比逐字节比较它们的内容快三倍。@silky:MD5是一个死哈希加密,对它作为大文件的比较哈希几乎没有影响。@Tanzelax:学会阅读@科克西姆拉:对不起?与严格的逐字节计算相比,计算MD5(通过各种数学运算逐字节完成)的速度究竟有多快。这是不可能的。@silky:性能下降是由于ReadByte
调用的开销造成的,MD5使用Read
,每次将4k字节读入字节[]
。
using (var reader1 = new System.IO.FileStream(filepath1, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var reader2 = new System.IO.FileStream(filepath2, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
byte[] hash1;
byte[] hash2;
using (var md51 = new System.Security.Cryptography.MD5CryptoServiceProvider())
{
md51.ComputeHash(reader1);
hash1 = md51.Hash;
}
using (var md52 = new System.Security.Cryptography.MD5CryptoServiceProvider())
{
md52.ComputeHash(reader2);
hash2 = md52.Hash;
}
int j = 0;
for (j = 0; j < hash1.Length; j++)
{
if (hash1[j] != hash2[j])
{
break;
}
}
if (j == hash1.Length)
{
Console.WriteLine("The files were equal.");
}
else
{
Console.WriteLine("The files were not equal.");
}
}
}