基于WPF实现简单的文件夹比较工具
作者:wzwyc 发布时间:2023-11-15 16:08:34
标签:WPF,文件夹,比较
文件比较平常都是用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/p/17427322.html
0
投稿
猜你喜欢
- 1. 前言在Java开发中接触的开发者大多数不太注重对接口的测试,结果在联调对接中出现各种问题。也有的使用Postman等工具进行测试,虽然
- 一、DES加密和解密package com.itjh.javaUtil;import java.io.UnsupportedEncoding
- 方法一:1.在pom.xml文件下添加依赖包<dependency><groupId>com.alibaba<
- 打包发布jar包部署相对较为简单,尤其是在分布式服务比较多的情况下。单体项目如果是单体项目,只需要找到maven的插件,点击package运
- 很久没写文章了,一方面是最近几个月比较忙,没太多时间,另一方面是最近拖延症严重,写文章的想法总是一拖再拖。今天找一个小案例写一下,与懒惰对抗
- 在工作上,我最近对一个现有的Java项目代码进行了清理。完成之后,我发现了一些反复出现的不规范代码。所以,我把它们整理成了一个列表出来分享给
- 本文介绍了java web每天定时执行任务,分享给大家,具体如下:第一步:package com.eh.util;import java.u
- 概述ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是
- switch结构(开关语句)的语法switch(表达式 ){--->类型为int、char case 常量1 :---&g
- springboot多模块化整合mybatis,mapper自动注入失败问题启动类添加@MapperScan或@ComponentScan,
- 工作中一直都是一个人奋战一人一个项目,使用maven管理,看这个也挺好,但是总感觉没有充分发挥maven的功能,于是研究了一下这个,网上关于
- 本文提纲版本约定JDK:8Servlet:4.xtomcat:9.x✍正文什么样的答案终身难忘?学生时代关于记忆经常能听见两种论调:死记硬背
- 目录服务注册服务发现服务注册引入相关依赖:<?xml version="1.0" encoding="U
- JdbcTypeInterceptor运行时自动添加 jdbcType 属性 * 签名@Intercepts({
- 基础铺垫在java中,关于json的lib有很多,比如jackjson、fastjson、gson等等,本人都用过,但是对于我等只需要让ja
- 一、前言近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目A中切换数据源,直接把数据写入项目B的数据库中。
- 队列的定义:队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。 (1)允许删除的一端称为队头(Fro
- Spring Security和Shiro的区别相同点1、认证功能2、授权功能3、加密功能4、会话管理5、缓存支持6、rememberMe功
- 本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等。 在下面的描述中,将以&
- java 设计模式之单例模式前言:在软件开发过程中常会有一些对象我们只需要一个,如:线程池(threadpool)、缓存(cac