cro*_*ono 125 .net c# checksum large-files
我必须在一些机器上同步大文件.这些文件最大可达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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是运行时:
- 使用带有1,6 GB文件的SHA256 - > 20分钟
- 使用带有1.6 GB文件的MD5 - > 6.15分钟
是否有更好 - 更快 - 获得校验和的方法(可能具有更好的散列函数)?
Ant*_*lev 110
这里的问题是一次SHA256Managed读取4096个字节(继承FileStream和覆盖Read(byte[], int, int)以查看它从文件流中读取了多少),这对于磁盘IO来说太小了.
为了加快速度(2分钟散列的2 Gb我机SHA256,1分钟MD5上的文件)包裹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
}
Run Code Online (Sandbox Code Playgroud)
Bin*_*ier 61
不要校验整个文件,每100mb左右创建校验和,因此每个文件都有一组校验和.
然后,在比较校验和时,您可以在第一个不同的校验和之后停止比较,提前退出,并避免处理整个文件.
它仍然需要相同文件的全部时间.
Tal*_*oni 44
正如Anton Gogolev所指出的,FileStream默认情况下一次读取4096个字节,但您可以使用FileStream构造函数指定任何其他值:
new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 16 * 1024 * 1024)
Run Code Online (Sandbox Code Playgroud)
请注意,2004年Microsoft的Brad Abrams写道:
围绕FileStream包装BufferedStream没有任何好处.我们大约4年前将BufferedStream的缓冲逻辑复制到FileStream中,以鼓励更好的默认性能
Chr*_*rkl 22
调用md5sum.exe的Windows端口.它的速度大约是.NET实现速度的两倍(至少在使用1.2 GB文件的机器上)
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 ();
}
Run Code Online (Sandbox Code Playgroud)
And*_*ers 10
我使用缓冲区大小进行测试,运行此代码
using (var stream = new BufferedStream(File.OpenRead(file), bufferSize))
{
SHA256Managed sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
}
Run Code Online (Sandbox Code Playgroud)
我测试了一个29½GB的文件,结果是
我正在运行i5 2500K CPU,12 GB RAM和OCZ Vertex 4 256 GB SSD驱动器.
所以我想,标准的2TB硬盘怎么样?结果是这样的
所以我建议不要缓冲或最大1磨的缓冲.
| 归档时间: |
|
| 查看次数: |
94446 次 |
| 最近记录: |