通过计算MD5获取重复的文件列表

我有一个包含文件路径的数组,我想列出那些基于MD5重复的文件。 我像这样计算他们的MD5:

private void calcMD5(Array files) //Array contains a path of all files { int i=0; string[] md5_val = new string[files.Length]; foreach (string file_name in files) { using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(file_name)) { md5_val[i] = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower(); i += 1; } } } } 

从上面我能够计算他们的MD5,但是如何只获得那些重复的文件的列表。 如果还有其他方法可以让我知道,我也是Linq的新手

1.重写calcMD5函数以获取单个文件路径并返回 MD5。
2.如果可能,将文件名存储在string[]List ,而不是非类型化数组。
3.使用以下LINQ获取具有相同哈希的文件组:

 var groupsOfFilesWithSameHash = files // or files.Cast() if you're stuck with an Array .GroupBy(f => calcMD5(f)) .Where(g => g.Count() > 1); 

4.您可以使用嵌套的foreach循环访问组,例如:

 foreach(var group in groupsOfFilesWithSameHash) { Console.WriteLine("Shared MD5: " + g.Key); foreach (var file in group) Console.WriteLine(" " + file); } 
  static void Main(string[] args) { // returns a list of file names, which have duplicate MD5 hashes var duplicates = CalcDuplicates(new[] {"Hello.txt", "World.txt"}); } private static IEnumerable CalcDuplicates(IEnumerable fileNames) { return fileNames.GroupBy(CalcMd5OfFile) .Where(g => g.Count() > 1) // skip SelectMany() if you'd like the duplicates grouped by their hashes as group key .SelectMany(g => g); } private static string CalcMd5OfFile(string path) { // I took your implementation - I don't know if there are better ones using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(path)) { return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower(); } } } 

而不是返回MD5哈希所有文件的数组,而是这样做:

  • 有一个’calculateFileHash()’方法。
  • 创建要测试的文件名数组。
  • 做这个:

    var dupes = Filenames.GroupBy(fn => calculateFileHash(fn))。其中(gr => gr.Count> 1);

这将返回一组组,每组是一个可枚举的,包含彼此具有相同内容的文件名。

 var duplicates = md5_val.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key); 

这将为您提供在数组中重复的哈希列表。

获取名称而不是哈希:

 var duplicates = md5_val.Select((x,i) => new Tuple(x, i)) .GroupBy(x => x.Item1) .Where(x => x.Count() > 1) .SelectMany(x => files[x.Item2].ToList()); 
  private void calcMD5(String[] filePathes) //Array contains a path of all files { Dictionary hashToFilePathes = new Dictionary(); foreach (string file_name in filePathes) { using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(file_name)) { //This will get you dictionary where key is md5hash and value is filepath hashToFilePathes.Add(BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower(), file_name); } } } // Here will be all duplicates List listOfDuplicates = hashToFilePathes.GroupBy(e => e.Key).Where(e => e.Count() > 1).SelectMany(e=>e).Select(e => e.Value).ToList(); } }