2015-06-29 113 views
1

如果我可以請求一些幫助,我有一個問題,我想打開一個文件夾顯示每個文件及其散列,然後在顯示結束文件我想要散列來顯示總文件夾結構。下面的代碼不正確,因爲它將路徑MD5添加到文件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

爲什麼你循環遍歷你的'files'數組兩次? (一次使用'foreach'並且再次使用'int i'。這就是爲什麼每次都得到一個總散列,因爲每次散列所有文件 –

回答

1

下面是將輸出您想要的輸出和要求的代碼。
請閱讀代碼中的「注意」部分以獲取更多信息。

不應該運行這在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。

+0

除了某些原因,MD5散列沒有匹配我的Python MD5腳本,也不匹配Microsoft文件完整性驗證程序生成的哈希腳本... fciv.exe Python腳本和fciv在文件上給出相同的結果。 – Exception

+0

@Exception是否包含字節將每個文件的路徑字符串轉換爲Python和MFIV中生成的哈希值?如果刪除將路徑字節添加到MD5的部分,哈希值應該匹配 –

+0

對不起,我一直在評論一切,改變事情一個小時,仍然不能得到它的工作,如果我註釋掉你說你添加散列末尾路徑的部分我得到一個異常,說明散列值必須在散列值之前完成檢索。 – Exception

相關問題