C# MD5文件夹中的每个文件以及文件夹中的每个文件

C# MD5文件夹中的每个文件以及文件夹中的每个文件,c#,hash,md5,C#,Hash,Md5,如果我能就我遇到的问题寻求帮助,我想打开一个文件夹,显示每个文件及其哈希,然后在显示的文件末尾显示一个哈希,以显示整个文件夹结构。下面的代码不正确,因为它将路径MD5添加到文件MD5中 下面的代码在列表框中显示每个文件,在列表框下显示一个散列,但散列代码是文件夹的散列,仅对每个文件重复 private void btnFolder_Click(object sender, EventArgs e) { DialogResult result = folderBrowser

如果我能就我遇到的问题寻求帮助,我想打开一个文件夹,显示每个文件及其哈希,然后在显示的文件末尾显示一个哈希,以显示整个文件夹结构。下面的代码不正确,因为它将路径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;
        }
    }
private void btnFolder\u单击(对象发送者,事件参数e)
{
DialogResult=folderBrowserDialog1.ShowDialog();
if(result==DialogResult.OK)
{
_路径=folderBrowserDialog1.SelectedPath;
Text=\u路径;
//假设要包括嵌套文件夹
var files=Directory.GetFiles(_路径,“***”,SearchOption.TopDirectoryOnly)
.OrderBy(p=>p.ToList();
foreach(文件中的字符串项)
{
MD5 MD5=MD5.Create();
对于(int i=0;i

提前感谢您的帮助。

下面是将输出所需输出和要求的代码。
有关更多信息,请阅读代码中的“注意”部分

不应在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。

为什么要在
文件
数组中循环两次?(一次是使用
foreach
,另一次是使用
for int i
。这就是为什么每次都会得到一个总哈希值,因为每次解决方案工作时都会对所有文件进行哈希,除了某些原因,MD5哈希值与我使用的Python MD5脚本不匹配,也与Microsoft File Integrity Verif生成的哈希值不匹配ier…fciv.exe Python脚本和fciv对文件都给出相同的结果。@例外情况是您是否将每个文件的路径字符串字节包含到Python和MFIV中生成的哈希中?如果删除将路径字节添加到MD5的部分,哈希应该匹配。抱歉,伙计,我已经注释了所有内容并更改了将事情处理了一个小时,仍然无法让它工作,如果我注释掉您声明将路径添加到哈希末尾的部分,我会得到一个异常,说明必须在检索哈希值之前完成哈希。@将路径字节添加到MD5的异常是根据您的原始代码进行的,如果不是这样的话恩,我可以修改代码,不这样做。你设置它在列表框中显示的方式是我所追求的,即显示整个文件夹的MD5,然后显示其中的每个文件,每个文件都有MD5,而没有文件路径MD5添加到文件中。我将编辑原始的帖子描述。我认为这是其他人喜欢的一个好解决方案。我将读取数百GB的文件,并且您的解决方案很好地使用了字节读取选项。