c# - 在 C# 中为大文件创建校验和的最快方法是什么

标签 c# .net large-files checksum

我必须在一些机器上同步大文件。文件最大可达 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);
    }
}

问题是运行时间:
- 使用带有 1.6 GB 文件的 SHA256 -> 20 分钟
- 带有 1.6 GB 文件的 MD5 -> 6.15 分钟

是否有更好、更快的方法来获取校验和(可能使用更好的哈希函数)?

最佳答案

这里的问题是 SHA256Managed 一次读取 4096 个字节(继承自 FileStream 并覆盖 Read(byte[], int, int) 以查看它从文件流中读取了多少),这对于磁盘 IO 来说太小了。

为了加快处理速度(在我的机器上使用 SHA256 散列 2 Gb 文件需要 2 分钟,MD5 需要 1 分钟)将 FileStream 包装在 BufferedStream 中并设置合理大小的缓冲区大小(我尝试使用 ~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
}

关于c# - 在 C# 中为大文件创建校验和的最快方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1177607/

相关文章:

xml - PowerShell 在读取大型 (50 MB) XML 文档时抛出 System.OutOfMemoryException

c++ - 像 iostream 这样的大型包含文件是否有效? (C++)

c# - 我应该使用哪个 .net 图表库?

c# - 为什么 C# 编译器不能将文字负值转换为枚举?

c# - 从自定义控件绑定(bind)到 ObservableCollection

c# - PostSharp.Sdk.CodeModel.AssemblyLoadException : Cannot find assembly 'mscorlib, 版本=2.0.5.0

c# - RijndaelManaged 的​​ AES OFB 加密

algorithm - 置换外部存储器的实用算法

c# - 类型引用找不到名为 '{clr-namespace :xxx}ClassName on MergedDictionary

c# - 将乘法转换为字符串