如何使用.NET检查2个文件是否相等?

Mic*_*hel 17 c#

说我有一个文件A.doc.
然后我将它复制到b.doc并将其移动到另一个目录.
对我来说,它仍然是同一个文件.
但我怎么能确定它呢?
当我下载文件时,我有时会读到关于获取mda5的东西或校验和,但我不知道那是什么.

有没有办法检查这些文件是否是二进制相等的?

Cox*_*oxy 15

如果你想100%确定文件中的确切字节是相同的,那么打开两个流并比较文件的每个字节是唯一的方法.

如果你只是想确定(99.9999%?),我会计算每个文件的MD5哈希并比较哈希.查看System.Security.Cryptography.MD5CryptoServiceProvider.

在我的测试中,如果文件通常是等效的,那么比较MD5哈希值比比较文件的每个字节快三倍.
如果文件通常不同,那么逐字节比较会快得多,因为您不必读取整个文件,只要单个字节不同就可以停止.

编辑:我最初根据快速测试得出这个答案,该测试从每个文件逐字节读取,并逐字节地比较它们.我错误地认为System.IO.FileStream的缓冲特性可以避免担心硬盘块大小和读取速度; 这不是真的.我重新测试了我的程序,它从4096个字节块中读取每个文件,然后比较块 - 这个方法总体上比MD5略快,即使文件完全相同,如果它们不同,当然会快得多.

我将这个答案留给了关于FileStream类的温和警告,因为我仍然觉得它有一些价值作为"我如何计算.NET中文件的MD5"的答案.除此之外,它不是满足原始​​请求的最佳方式.

计算两个文件的MD5哈希值的示例(现已测试!):

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.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @silky:MD5是一个死密码加密,对于它作为大文件的比较哈希使用几乎没有影响. (8认同)
  • @silky:性能下降是由于`ReadByte`调用的开销,其中MD5改为使用`Read`,每次读取4k字节到`byte []`. (8认同)
  • 虽然这段代码"更短",但它肯定要慢得多,而且通常比逐字节比较差.更不用说MD5是一个死哈希(加密语言).如果您只是想检查文件是否相同,我真的不会这样做. (4认同)
  • @Tanzelax:学会阅读.@coxymla:对不起?究竟如何更快地计算MD5(使用各种数学运算逐字节完成)而不是*严格*逐字节.这是不可能的. (2认同)

use*_*637 9

首先比较文件的大小,如果大小不一样则文件不同,如果大小相同,则只需比较文件内容.