1

是否有任何快速算法允许比较两个文件(用于验证目的)而无需读取全部内容?

4

5 回答 5

2

您可以在这两个文件上使用 MD5 哈希并以这种方式进行比较。但是,它在技术上确实读取了整个文件。如果不检查我不认为,您将无法 100% 确定。

在 C# 中,可以通过以下方式执行此操作(抱歉,您没有提到特定语言):

protected string GetMD5HashFromFile(string fileName)
{
    byte[] retVal = { };

    using (FileStream file = new FileStream(fileName, FileMode.Open))
    using (MD5 md5 = new MD5CryptoServiceProvider())
    {
        retVal = md5.ComputeHash(file);
    }

    if (retVal.Length > 0)
    {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < retVal.Length; i++)
        {
            sb.Append(retVal[i].ToString("x2"));
        }

        return sb.ToString();
    }
    else
    {
        return string.Empty;
    }
}

bool CompareFiles(string fileName1, string fileName2)
{
    return (GetMD5HashFromFile(fileName1) == GetMD5HashFromFile(fileName2));
}
于 2010-03-10T19:14:51.193 回答
1

除非您读取每个字节,否则没有算法可以 100% 确定文件相同。证明很简单——假设存在这样的算法,我们用它来比较两个文件。这意味着算法不会读取一些字节数。我可以通过更改一个文件中的这些字节而不是另一个文件来导致算法失败。

于 2010-03-10T19:28:24.080 回答
1

在数学上不可能确定两个相同大小的文件不完全读取它们是相等的,但是很可能在不完全读取它们的情况下确定它们不相等。这可以通过各种方式完成,例如使用散列函数或短路比较。

于 2010-03-10T19:34:11.697 回答
1

您可以编写一个自定义 CRC 程序来读取文件的位。例如,每1k 16 个字节或类似的东西,而不是对整个文件进行CRC。当然,这样做的风险更大,因为数据可能会在您未查看的地方发生变化,并且不会对您比较的块产生影响。但是 CRC 也有点冒险,因为两个非常不同的数据集可能返回相同的值。

于 2010-03-10T19:17:14.307 回答
0

恐怕您无法避免完整阅读这两个文件以完全确定它们是平等的。

您可以先检查两个文件的大小;如果它们不同,则文件不同(但是仅在行分隔符上有所不同的文本文件呢?)。

如果大小相同,我看不到任何正确的方法可以走得更远,但开始读取这两个文件。当然,它可以在缓冲区不同时立即停止,但它只能说明文件在处理完最后一个字符时确实相等。

于 2010-03-10T19:20:45.270 回答