1. ホーム
  2. c#

[解決済み] C#で大きなファイルのチェックサムを作成する最速の方法は何ですか?

2022-06-24 22:20:05

質問

いくつかのマシン間で大きなファイルを同期する必要があります。ファイルのサイズは最大で 6GB です。同期は、数週間ごとに手動で行われます。ファイル名はいつでも変更できるため、ファイル名を考慮することはできません。

私の計画は、宛先 PC とソース PC でチェックサムを作成し、次に、宛先にまだ存在しないチェックサム付きのすべてのファイルを宛先にコピーすることです。 私の最初の試みは、このようなものでした。

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 GB のファイル -> 20 分。

- MD5 で 1,6 GB のファイル -> 6.15 分

チェックサムを得るためのより良い - より速い - 方法はありますか(たぶん、より良いハッシュ関数で)?

どのように解決するのですか?

ここで問題となるのは SHA256Managed は一度に 4096 バイトを読み取ります (これは FileStream をオーバーライドし Read(byte[], int, int) をオーバーライドして、ファイルストリームからどれだけ読み込んだかを確認します)、これはディスクIOには小さすぎるバッファです。

スピードアップするために (私のマシンでは 2GB のファイルを SHA256 でハッシュするのに2分、MD5 でハッシュするのに1分) ラップ FileStreamBufferedStream で、適度な大きさのバッファサイズを設定します (私は ~1 Mb のバッファで試してみました)。

// Not sure if BufferedStream should be wrapped in using block
using(var stream = new BufferedStream(File.OpenRead(filePath), 1200000))
{
    // The rest remains the same
}