Быстрая проверка целостности файлов - PullRequest
1 голос
/ 10 марта 2010

Существует ли какой-либо быстрый алгоритм, позволяющий сравнивать два файла (для целей проверки) без необходимости считывать все содержимое?

Ответы [ 5 ]

2 голосов
/ 10 марта 2010

Вы можете использовать хеш 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));
}
1 голос
/ 10 марта 2010

Математически невозможно определить, что два файла одинакового размера равны, не прочитав их полностью, но очень возможно определить, что они не равны , не прочитав оба полностью. Это можно сделать различными способами, например, используя хэш-функции или сравнение коротких замыканий.

1 голос
/ 10 марта 2010

Не существует алгоритма, позволяющего на 100% быть уверенным, что файлы одинаковы, если вы не читаете каждый байт. Доказательство простое - предположим, что такой алгоритм существует, и мы используем его для сравнения двух файлов. Это подразумевает, что некоторое количество байтов не читается алгоритмом. Я могу вызвать сбой алгоритма, изменив эти байты в одном файле, но не в другом.

1 голос
/ 10 марта 2010

Вы можете написать собственную процедуру CRC, которая читает биты файла. например 16 байт на каждый 1 Кб или что-то в этом роде вместо CRCing всего файла. Конечно, это более рискованно, поскольку данные могут измениться, когда вы не смотрите, и не повлиять на сравниваемые блоки. Но CRC тоже немного рискован, поскольку два очень разных набора данных могут возвращать одно и то же значение.

0 голосов
/ 10 марта 2010

Боюсь, вы не сможете избежать полного чтения обоих файлов, чтобы быть полностью уверенными, что они равны.

Вы можете сначала проверить размер обоих файлов; если они разные, файлы разные (но как насчет текстовых файлов, которые будут отличаться только в разделителе строк?).

Если размер одинаковый, я не вижу правильного пути, но начинаю читать оба файла. Конечно, он может остановиться, как только буфер станет другим, но он может только указать, что файлы равны действительно , когда последний символ обрабатывается.

...