Сравнение файлов с использованием md5 ha sh или длины файла? - PullRequest
2 голосов
/ 06 августа 2020

У меня есть список файлов на диске, которые мне нужно получить и загрузить в память. Я создал класс FileConfig, как показано ниже, в котором есть все метаданные для каждого файла.

public class FileConfig
{
    public string FileName { get; set; }
    public DateTime Date { get; set; }
    public string FileContent { get; set; }
    public string MD5Hash { get; set; }
}

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

Ниже мой код, в котором я получаю список всех файлов с диска, а затем составляю из него список объектов FileConfig.

private IEnumerable<FileConfig> LoadFiles(string path)
{
    IList<string> files = procUtility.GetListOfFiles(path);
    if (files == null || files.Count == 0) { yield return default; }

    for (int i = 0; i < files.Count; i++)
    {
        var cfgPath = files[i];
        if (!File.Exists(cfgPath)) { continue; }
        var date = File.GetLastWriteTimeUtc(cfgPath);
        var content = File.ReadAllText(cfgPath);
        var pathPieces = cfgPath.Split(System.IO.Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
        var fileName = pathPieces[pathPieces.Length - 1];
        var md5Hash = procUtility.GetMD5Hash(cfgPath);
        yield return new FileConfig
        {
            FileName = fileName,
            Date = date,
            FileContent = content,
            MD5Hash = md5Hash
        };
    }
}

Моя цель в конце - сравнить файлы (а также использовать содержимое файла для каких-то других целей), поэтому я использовал строку MD5Hash каждого файла в классе FileConfig и выяснял, разные они или не как показано ниже:

!newFile.MD5Hash.Equals(oldFile.First().MD5Hash)

Есть ли лучший способ наследовать FileInfo класс в моем FileConfig классе, а затем использовать метод length каждого файла для сравнения? или что у меня здесь нормально?

1 Ответ

3 голосов
/ 06 августа 2020

То, что у вас есть, нормально. md5sum предназначен для генерации ha sh на основе содержимого файла; даже небольшая разница в байтах приведет к другому ha sh. Вероятность того, что вы сгенерируете ложные срабатывания при сравнении md5sums, исчисляется миллионами, и содержимое файлов должно сильно отличаться, чтобы иметь этот шанс.

Однако побайтовое сравнение может быть быстрее в вашем случае при генерации контрольных сумм загружают каждый байт файла и затем обрабатывают их. Если вам действительно требуется побайтовое сравнение, используйте System.IO.FileInfo и File.ReadAllBytes(FileInfo fileName).SequenceEqual(File.ReadAllBytes(FileInfo fileName)

Побайтовое сравнение заканчивается на первом различии, которое, как мы предполагаем, быстрее, чем сравнение md5sums как md5 ha sh генератор не заканчивается разницей.

Вы также можете использовать следующие для небинарных файлов:

File.ReadLines(file).SequenceEqual(File.ReadLines(file))

Что касается сравнения по длине, вы должны никогда не хочу полагаться на это. От добавления чека к нему пользы практически нет, а количество ложных срабатываний, возникающих из-за того, что полагается исключительно на чек, можно исчислить.

...