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

时间:2015-06-29 14:39:57

标签: c# hash md5

如果我可以请求帮助解决我遇到的问题,我想打开一个文件夹显示每个文件及其哈希值,然后在显示的文件的末尾我想要一个哈希来显示总文件夹结构。下面的代码不正确,因为它将路径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;
        }
    }

提前感谢您的任何帮助。

1 个答案:

答案 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。