咨询区
Dario:
我需要在多台机器间同步大文件,不过文件高达 6G,通常我都是每几周手工同步一次,考虑到文件的文件名经常变,为了检验一致性,我考虑使用 checksum
机制。
我的计划是在 源机器
和 目标机器
上做 校验和
,然后在机器间copy文件的时候带上校验和,从而判断文件的完整性,我尝试用下面的代码做这件事情。
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.6G 文件需要耗费 20分钟算校验和。
MD5 模式下,1.6G 文件需要6.15分钟算校验和。
请问是否有更高效的方式来计算 校验和 呢?
回答区
Anton Gogolev:
其实问题在于 SHA256Managed
一次只能读取 4096 byte,这对于 磁盘IO 的吞吐量来说实在太小了。
要想加速,可以用 BufferedStream 来包裹 FileStream,从而提高 FileStream 默认的 4096 的大小,不过这个值可以根据自己场景设置一个合理的范围,这里我设置成 1M
。
// Not sure if BufferedStream should be wrapped in using block
using(var stream = new BufferedStream(File.OpenRead(filePath), 1024 * 1024))
{// The rest remains the same
}
在我的机器上。
SHA256 模式下,2G 文件需要 2分钟 算校验和。
MD5 模式下,2G 文件需要 1分钟 算校验和。
Fabske:
你可以了解一下 XxHash.Net
, github地址:https://github.com/wilhelmliao/xxHash.NET
而且 xxHash
算法看起来是最快的,下面是 xxHash 的 benchmark 图。
具体参考 github:https://github.com/Cyan4973/xxHash
点评区
说起 checksum
,让我想起来了计算机网络原理
,感觉是这门课中最多的一个词 ????????????,TCP,UDP 包无不有 checksum,它的作用大多还是怕在网络传输中由于干扰丢了一些字节,这样 checksum 就能精准的发现,不过我记得 redis 的 xxx.rdb 文件中也是有 checksum
的, 这玩意真的太重要了。