整理硬盘时最头疼的就是重复文件。本示例用 Directory.EnumerateFiles 递归列出全部文件,逐个计算 MD5 并按哈希分组,只要某组多于一个文件即为重复,便于后续人工确认删除。
实现思路
用字典以 MD5 为键、文件路径列表为值聚合;GetMd5 借助 MD5.ComputeHash 配合文件流读取,最后按分组打印。权限不足的目录会抛异常,遍历时用 try/catch 跳过即可。
完整代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
class Program
{
static void Main(string[] args)
{
string root = args.Length > 0 ? args[0] : "D:/";
var map = new Dictionary<string, List<string>>(); // md5 -> 路径列表
foreach (string file in SafeEnumerate(root))
{
string md5 = GetMd5(file);
if (!map.ContainsKey(md5)) map[md5] = new List<string>();
map[md5].Add(file);
}
int total = 0;
foreach (var pair in map)
{
if (pair.Value.Count < 2) continue;
total += pair.Value.Count - 1;
Console.WriteLine("MD5: " + pair.Key);
foreach (string path in pair.Value)
Console.WriteLine(" " + path);
}
Console.WriteLine("可清理重复文件数:" + total);
}
static IEnumerable<string> SafeEnumerate(string root)
{
foreach (string file in Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories))
{
try { yield return file; }
catch (UnauthorizedAccessException) { /* 无权限跳过 */ }
catch (IOException) { /* 被占用跳过 */ }
}
}
static string GetMd5(string path)
{
using (var md5 = MD5.Create())
using (var stream = File.OpenRead(path))
{
byte[] hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
}使用建议
- 先输出分组人工核对,确认无误再删除,避免误删同名不同内容文件;
- 大文件较多时先比文件大小再比 MD5 可显著提速;
- 跨盘符扫描建议输出清单后用资源管理器复核。
小结
MD5 分组是目前最可靠的重复文件判定手段之一,把同样的思路稍作改造,还能用于备份完整性校验与资源指纹统计。
评论(0)
暂无评论,快来抢沙发吧~