文件夹比较工具
文件比较平常都是用Beyond Compare,可以说离不开的神器,特别是针对代码比较这块,确实挺好用的。
不过Beyond Compare平常拿它主要是用来做代码比较,用来做一些大批量的二进制文件比较,其实有点不是很方便。
于是造轮子,重新写了一个简单的文件夹比较的小工具。
平常主要是拿来做一些Nuget包的比对,应用包版本的比较。
文件夹比较逻辑,采用迭代比较的方式:
using CgdataBase; using FolderCompare.Models; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FolderCompare.Helpers { public static class CompareHelper { public static void CompareDirectory(CgDirectoryInfo path1, CgDirectoryInfo path2) { if (path1.Children.IsNullOrEmpty()) { if (path2.Children.IsNullOrEmpty()) { path1.Result = ECompareResult.匹配; path2.Result = ECompareResult.匹配; } else { path1.Result = ECompareResult.空; path2.Result = ECompareResult.孤立; SetCompareResult(path2, ECompareResult.匹配); } return; } if (path2.Children.IsNullOrEmpty()) { path1.Result = ECompareResult.孤立; path2.Result = ECompareResult.空; SetCompareResult(path1, ECompareResult.匹配); return; } var dirList = new List<string>(); var fileList = new List<string>(); dirList.AddRange(path1.Children.Where(s => s.IsDirectory).Select(s => s.Name)); dirList.AddRange(path2.Children.Where(s => s.IsDirectory).Select(s => s.Name)); fileList.AddRange(path1.Children.Where(s => !s.IsDirectory).Select(s => s.Name)); fileList.AddRange(path2.Children.Where(s => !s.IsDirectory).Select(s => s.Name)); var index = 0; if (dirList.HadItems()) { var items = dirList.Distinct().ToList(); items.Sort(); foreach (var item in items) { var dir1 = path1.Children.OfType<CgDirectoryInfo>().SingleOrDefault(s => s.Name == item); if (dir1 == null) { dir1 = new CgDirectoryInfo(); dir1.Result = ECompareResult.空; path1.Children.Insert(index, dir1); var dir2 = path2.Children.OfType<CgDirectoryInfo>().Single(s => s.Name == item); dir2.Result = ECompareResult.孤立; var old = path2.Children.IndexOf(dir2); path2.Children.Move(old, index); SetCompareResult(dir2, ECompareResult.匹配); } else { var dir2 = path2.Children.OfType<CgDirectoryInfo>().SingleOrDefault(s => s.Name == item); if (dir2 == null) { dir2 = new CgDirectoryInfo(); dir2.Result = ECompareResult.空; path2.Children.Insert(index, dir2); dir1.Result = ECompareResult.孤立; var old = path1.Children.IndexOf(dir1); path1.Children.Move(old, index); SetCompareResult(dir1, ECompareResult.匹配); } else { CompareDirectory(dir1, dir2); var old = path1.Children.IndexOf(dir1); path1.Children.Move(old, index); old = path2.Children.IndexOf(dir2); path2.Children.Move(old, index); } dir2.Index = index; } dir1.Index = index; index++; } } if (fileList.HadItems()) { var items = fileList.Distinct().ToList(); items.Sort(); foreach (var item in items) { var file1 = path1.Children.OfType<CgFileInfo>().SingleOrDefault(s => s.Name == item); if (file1 == null) { file1 = new CgFileInfo(); file1.Result = ECompareResult.空; path1.Children.Insert(index, file1); var file2 = path2.Children.OfType<CgFileInfo>().Single(s => s.Name == item); file2.Result = ECompareResult.孤立; var old = path2.Children.IndexOf(file2); path2.Children.Move(old, index); } else { var file2 = path2.Children.OfType<CgFileInfo>().SingleOrDefault(s => s.Name == item); if (file2 == null) { file2 = new CgFileInfo(); file2.Result = ECompareResult.空; path2.Children.Insert(index, file2); file1.Result = ECompareResult.孤立; var old = path1.Children.IndexOf(file1); path1.Children.Move(old, index); } else { CompareFile(file1, file2); var old = path1.Children.IndexOf(file1); path1.Children.Move(old, index); old = path2.Children.IndexOf(file2); path2.Children.Move(old, index); } file2.Index = index; } file1.Index = index; index++; } } path1.Result = GetCompareResult(path1.Children); path2.Result = GetCompareResult(path2.Children); } private static void CompareFile(CgFileSystemInfo info1, CgFileSystemInfo info2) { if (info1.Name.IsNullOrEmpty()) { info1.Result = ECompareResult.空; info2.Result = ECompareResult.孤立; return; } if (info2.Name.IsNullOrEmpty()) { info1.Result = ECompareResult.孤立; info2.Result = ECompareResult.空; return; } if (info1.Length == info2.Length && info1.LastWriteTime == info2.LastWriteTime) { info1.Result = ECompareResult.匹配; info2.Result = ECompareResult.匹配; } else { if (info1.LastWriteTime > info2.LastWriteTime) { info1.Result = ECompareResult.不匹配; info2.Result = ECompareResult.较旧的; } else { info1.Result = ECompareResult.较旧的; info2.Result = ECompareResult.不匹配; } } } private static void SetCompareResult(CgDirectoryInfo info, ECompareResult result) { if (info.Children.HadItems()) { foreach (var item in info.Children) { if (item is CgDirectoryInfo dir) { dir.Result = result; SetCompareResult(dir, result); } else if (item is CgFileInfo file) { file.Result = result; } } } } public static ECompareResult GetCompareResult(ObservableCollection<CgFileSystemInfo> items) { if (items.IsNullOrEmpty()) return ECompareResult.空; if (items.Any(s => s.Result == ECompareResult.不匹配 || s.Result == ECompareResult.较旧的)) return ECompareResult.不匹配; if (items.Any(s => s.Result == ECompareResult.孤立)) return ECompareResult.孤立; return ECompareResult.匹配; } } }
源码:https://gitee.com/wzwyc/FolderCompare