印峰 发表于 2023-5-24 12:22:49

文件夹比较工具

文件比较平常都是用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
 

来源:https://www.cnblogs.com/wzwyc/archive/2023/05/24/17427322.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 文件夹比较工具