Что является самым быстрым способом создать контрольную сумму для больших файлов в C#

Я должен синхронизировать большие файлы через некоторые машины. Файлы могут составить до 6 ГБ в размере. Синхронизация будет сделана вручную каждые несколько недель. Я не могу принять имя файла во внимание, потому что они могут измениться в любое время.

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

using System.IO;
using System.Security.Cryptography;

private static string GetChecksum(string file)
{
    using (FileStream stream = File.OpenRead(file))
    {
        SHA256Managed sha = new SHA256Managed();
        byte[] checksum = sha.ComputeHash(stream);
        return BitConverter.ToString(checksum).Replace("-", String.Empty);
    }
}

Проблемой было время выполнения:
- с SHA256 с Файлом на 1,6 ГБ-> 20 минут
- с MD5 с Файлом на 1,6 ГБ-> 6,15 минут

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

125
задан Hooman Bahreini 1 October 2019 в 02:49
поделиться

5 ответов

Если вам действительно нужно, чтобы это работало так, я бы сделал это (чтобы убедиться, что он работает с помощью клавиатуры и мыши)

  • Добавьте обработчик события onfocus в select, чтобы установить «текущий»

    // Not sure if BufferedStream should be wrapped in using block
    using(var stream = new BufferedStream(File.OpenRead(filePath), 1200000))
    {
        // The rest remains the same
    }
    
110
ответ дан 24 November 2019 в 00:59
поделиться

Не проверяйте контрольную сумму для всего файла, создавайте контрольные суммы каждые 100 МБ или около того, поэтому каждый файл имеет набор контрольных сумм.

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

Это все равно займет полное время для идентичных файлов.

61
ответ дан 24 November 2019 в 00:59
поделиться

Вызов порта Windows md5sum.exe . Это примерно в два раза быстрее, чем реализация .NET (по крайней мере, на моем компьютере с файлом размером 1,2 ГБ)

public static string Md5SumByProcess(string file) {
    var p = new Process ();
    p.StartInfo.FileName = "md5sum.exe";
    p.StartInfo.Arguments = file;            
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    p.WaitForExit();           
    string output = p.StandardOutput.ReadToEnd();
    return output.Split(' ')[0].Substring(1).ToUpper ();
}
22
ответ дан 24 November 2019 в 00:59
поделиться

Вы делаете что-то неправильно (вероятно, слишком маленький буфер чтения). На машине невысокого возраста (Athlon 2x1800MP с 2002 года), на диске которой есть DMA, вероятно, неисправен (6,6 Мбит / с чертовски медленно при выполнении последовательных чтений):

Создайте файл размером 1 ГБ со «случайными» данными:

# dd if=/dev/sdb of=temp.dat bs=1M count=1024    
1073741824 bytes (1.1 GB) copied, 161.698 s, 6.6 MB/s

# time sha1sum -b temp.dat
abb88a0081f5db999d0701de2117d2cb21d192a2 *temp.dat

1м5.

2
ответ дан 24 November 2019 в 00:59
поделиться

Ok - thanks to all of you - let me wrap this up:

  1. using a "native" exe to do the hashing took time from 6 Minutes to 10 Seconds which is huge.
  2. Increasing the buffer was even faster - 1.6GB file took 5.2 seconds using MD5 in .Net, so I will go with this solution - thanks again
16
ответ дан 24 November 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: