如果我可以请求帮助解决我遇到的问题,我想打开一个文件夹显示每个文件及其哈希值,然后在显示的文件的末尾我想要一个哈希来显示总文件夹结构。下面的代码不正确,因为它将路径MD5添加到文件MD5。
下面的代码显示列表框中的每个文件,然后是哈希值,但哈希码是刚为每个文件重复的文件夹的哈希值。
private void btnFolder_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
_path = folderBrowserDialog1.SelectedPath;
txtFolder.Text = _path;
// assuming you want to include nested folders
var files = Directory.GetFiles(_path, "*.*", SearchOption.TopDirectoryOnly)
.OrderBy(p => p).ToList();
foreach (string items in files)
{
MD5 md5 = MD5.Create();
for (int i = 0; i < files.Count; i++)
{
string file = files[i];
// hash path
string relativePath = file.Substring(_path.Length + 1);
byte[] pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLower());
md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
// hash contents
byte[] contentBytes = File.ReadAllBytes(file);
if (i == files.Count - 1)
md5.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
else
md5.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0);
}
lstBox.Items.Add(items);
lstBox.Items.Add(BitConverter.ToString(md5.Hash).Replace("-", "").ToLower());
}
}
else
{
return;
}
}
提前感谢您的任何帮助。
答案 0 :(得分:1)
以下是输出所需输出和要求的代码 有关详细信息,请阅读代码中的“NOTE”部分。
你不应该在 UI线程中运行它,因为它会锁定它直到所有文件都被处理完毕。请将重构您的方法看成可以在线程中调用的内容。
private void btnFolder_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
_path = folderBrowserDialog1.SelectedPath;
txtInput.Text = _path;
// assuming you want to include nested folders
var files = Directory.GetFiles(_path, "*.*", SearchOption.TopDirectoryOnly)
.OrderBy(p => p).ToList();
MD5 totalMD5 = MD5.Create();
int bytesToReadAtOnce = 2048; // NOTE: This can be changed to bigger or smaller.
foreach (string singleFile in files)
{
MD5 singleMD5 = MD5.Create();
// hash contents
// NOTE: This is nice for small files, but a memory eater for big files
//byte[] contentBytes = File.ReadAllBytes(singleFile);
//singleMD5.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
using (FileStream inputFile = File.OpenRead(singleFile))
{
byte[] content = new byte[bytesToReadAtOnce];
int bytesRead = 0;
// Read the file only in chunks, allowing minimal memory usage.
while ((bytesRead = inputFile.Read(content, 0, bytesToReadAtOnce)) > 0)
{
totalMD5.TransformBlock(content, 0, bytesRead, content, 0);
singleMD5.TransformBlock(content, 0, bytesRead, content, 0);
}
// Close the singleMD5 block with 0 length
singleMD5.TransformFinalBlock(content, 0, 0);
// Output per file
lstBox.Items.Add(string.Format("File: {0}", singleFile));
lstBox.Items.Add(string.Format("MD5 : {0}", BitConverter.ToString(singleMD5.Hash).Replace("-", "").ToUpper()));
}
}
// Close the totalMD5 with an empty byte[] and 0 length (basically does nothing but close the Block)
totalMD5.TransformFinalBlock(new byte[0], 0, 0);
// Output for total
lstBox.Items.Insert(0, Environment.NewLine);
lstBox.Items.Insert(0, string.Format("Total MD5 : {0}", BitConverter.ToString(totalMD5.Hash).Replace("-", "").ToUpper()));
lstBox.Items.Insert(0, string.Format("Root Path : {0}", _path));
}
else
{
return;
}
}
如果更改为仅以块的形式读取每个文件,我意外让此代码在其中包含287k个文件的文件夹上运行,总大小约为41GB。 在整个目录处理过程中,内存使用量不超过7MB。