using System.Text.Json.Serialization; namespace Common; public enum DirOrFile { Dir = 0, File = 1, } public enum NextOpType { Add = 0, Modify = 1, Del = 2 } [JsonDerivedType(typeof(AFileOrDir), typeDiscriminator: 1)] [JsonDerivedType(typeof(File), typeDiscriminator: 2)] [JsonDerivedType(typeof(Dir), typeDiscriminator: 3)] public class AFileOrDir { public DirOrFile Type { get; set; } public NextOpType? NextOp { get; set; } // private string Path = path; /// /// 全部为绝对路径... 占用资源会大一点,但是完全OK /// /// public required string Path { get; set; } /// /// 相当于Path 包装,天杀的windows在路径字符串中使用两种分隔符,“/” 和“\”,这导致,即使两个字符串不相同,也可能是同一个路径。现在把它们统一起来 /// public string FormatedPath { get { return Path.Replace("\\", "/"); } set { Path = value; } } // public bool IsEqual(AFileOrDir other) // { // return false; // } public static int Compare(AFileOrDir l, AFileOrDir r) { var pv = l.FormatedPath.CompareTo(r.FormatedPath); if (pv == 0) { pv = l.Type.CompareTo(r.Type); } return pv; } } /// /// 文件 /// /// 绝对路径 /// 文件的修改时间/ public class File : AFileOrDir { public File() { Type = DirOrFile.File; } public required DateTime MTime { get; set; } public bool IsEqual(AFileOrDir other) { if (other is not File otherFile) { return false; } else { var r = this.MTime == otherFile.MTime && this.FormatedPath == otherFile.FormatedPath && this.NextOp == otherFile.NextOp; return r; } } } public class Dir : AFileOrDir { public Dir() { Type = DirOrFile.Dir; } public required List Children { get; set; } public bool IsEqual(AFileOrDir other) { if (other is not Dir otherDir) { return false; } else { if (this.FormatedPath != otherDir.FormatedPath || this.NextOp != otherDir.NextOp) { return false; } if (this.Children.Count != otherDir.Children.Count) { return false; } this.Children.Sort(AFileOrDir.Compare); otherDir.Children.Sort(AFileOrDir.Compare); for (int i = 0; i < this.Children.Count; i++) { var l = this.Children[i]; var r = otherDir.Children[i]; if (l is Dir ld && r is Dir rd) { if (!ld.IsEqual(rd)) { return false; } } else if (l is File lf && r is File rf) { if (!lf.IsEqual(rf)) { return false; } } else { return false; } } return true; } } }