From a70a302134330d686c2cfbabd2688e239b406675 Mon Sep 17 00:00:00 2001
From: zerlei <1445089819@qq.com>
Date: Tue, 24 Sep 2024 14:27:39 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E4=BA=86dir?=
=?UTF-8?q?=E7=9A=84=E7=BB=93=E6=9E=84=EF=BC=8C=E4=BB=A5=E4=BE=BF=E4=BA=8E?=
=?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96=E5=92=8C=E5=8F=8D=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Server/Common/Dir.cs | 1079 ++++++++++++++++------------
Server/Common/FileDirBase.cs | 59 +-
Server/LocalServer/StateHelper.cs | 6 +-
Server/RemoteServer/StateHelper.cs | 2 +-
Server/ServerTest/DirFileOpTest.cs | 15 +-
Server/ServerTest/FilesSeed.cs | 353 +++++----
Server/ServerTest/PipeTest.cs | 82 +--
7 files changed, 954 insertions(+), 642 deletions(-)
diff --git a/Server/Common/Dir.cs b/Server/Common/Dir.cs
index 98fef39..c32a0e8 100644
--- a/Server/Common/Dir.cs
+++ b/Server/Common/Dir.cs
@@ -1,132 +1,367 @@
namespace Common;
-///
-/// 文件夹结构,它包含文件和文件夹
-///
-/// 绝对路径
-/// 子文件或文件夹
-public class Dir(string path, List? children = null, NextOpType? nextOp = null)
- : AFileOrDir(path, DirOrFile.Dir, nextOp)
+public static class DirExtension
{
- public List Children { get; set; } = children ?? [];
- public override bool IsEqual(AFileOrDir other)
+ ///
+ /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有
+ /// 节点都会打上标记
+ /// 文件夹的 NextOp 只有新增和删除
+ ///
+ ///
+ ///
+ /// 右侧版本接下来进行的操作
+ public static Dir Diff(this Dir thisDir, Dir other)
{
- if (other is not Dir otherDir)
+ var ldir = thisDir;
+ var rdir = other;
+ Dir? cDir = new() { Path = rdir.FormatedPath, Children = [] };
+ //分别对文件和文件夹分组
+ List lFiles = [];
+ List rFiles = [];
+ List lDirs = [];
+ List rDirs = [];
+ var lGroups = ldir.Children.GroupBy(x => x.Type);
+ var rGroups = rdir.Children.GroupBy(x => x.Type);
+ foreach (var g in lGroups)
{
- return false;
+ if (g.Key == DirOrFile.Dir)
+ {
+ lDirs = g.AsEnumerable()
+ .Select(n =>
+ {
+ if (n is Dir dir)
+ {
+ return dir;
+ }
+ throw new Exception("cannot be here");
+ })
+ .ToList();
+ }
+ else
+ {
+ lFiles = g.AsEnumerable()
+ .Select(n =>
+ {
+ if (n is File file)
+ {
+ return file;
+ }
+ throw new Exception("cannot be here");
+ })
+ .ToList();
+ }
}
- else
+
+ foreach (var g in rGroups)
{
- if (this.FormatedPath != otherDir.FormatedPath || this.NextOp != otherDir.NextOp)
+ if (g.Key == DirOrFile.Dir)
{
- return false;
+ rDirs = g.AsEnumerable()
+ .Select(n =>
+ {
+ if (n is Dir dir)
+ {
+ return dir;
+ }
+ throw new Exception("cannot be here");
+ })
+ .ToList();
}
- if (this.Children.Count != otherDir.Children.Count)
+ else
{
- return false;
+ rFiles = g.AsEnumerable()
+ .Select(n =>
+ {
+ if (n is File file)
+ {
+ return file;
+ }
+ throw new Exception("cannot be here");
+ })
+ .ToList();
}
- this.Children.Sort(AFileOrDir.Compare);
- otherDir.Children.Sort(AFileOrDir.Compare);
- for (int i = 0; i < this.Children.Count; i++)
+ }
+
+ //排序,然后对比
+ int lIndex_f = 0;
+ int rIndex_f = 0;
+ int lIndex_d = 0;
+ int rIndex_d = 0;
+ lFiles.Sort(AFileOrDir.Compare);
+ rFiles.Sort(AFileOrDir.Compare);
+ lDirs.Sort(AFileOrDir.Compare);
+ rDirs.Sort(AFileOrDir.Compare);
+ //对比文件
+ while (true)
+ {
+ //当两个线性表都走到最后时,退出循环
+ if (lIndex_f == lFiles.Count && rIndex_f == rFiles.Count)
{
- if (!this.Children[i].IsEqual(otherDir.Children[i]))
+ break;
+ }
+ //左侧先到底,右侧都是将要删除的
+ if (lIndex_f == lFiles.Count)
+ {
+ var er = rFiles[rIndex_f];
+ cDir.Children.Add(
+ new File
+ {
+ Path = er.FormatedPath,
+ MTime = er.MTime,
+ NextOp = NextOpType.Del
+ }
+ );
+ rIndex_f++;
+ continue;
+ }
+ //右侧先到底,左侧都是要添加的
+ if (rIndex_f == rFiles.Count)
+ {
+ var el = lFiles[lIndex_f];
+
+ cDir.Children.Add(
+ new File
+ {
+ Path = el.FormatedPath.Replace(ldir.FormatedPath, rdir.FormatedPath),
+ MTime = el.MTime,
+ NextOp = NextOpType.Add
+ }
+ );
+ lIndex_f++;
+ continue;
+ }
+ var l = lFiles[lIndex_f];
+ var r = rFiles[rIndex_f];
+ //将根路径差异抹平
+ var lreativePath = l.FormatedPath.Replace(ldir.FormatedPath, "");
+ var rreativePath = r.FormatedPath.Replace(rdir.FormatedPath, "");
+ //两文件相同,对比文件修改时间,不同增加到diff内容
+ if (lreativePath == rreativePath)
+ {
+ lIndex_f++;
+ rIndex_f++;
+ if (l.MTime != r.MTime)
{
- return false;
+ cDir.Children.Add(
+ new File
+ {
+ Path = r.FormatedPath,
+ MTime = l.MTime,
+ NextOp = NextOpType.Modify
+ }
+ );
}
}
- return true;
- }
- }
-
- ///
- /// clone, 但是更改根目录
- ///
- /// 操作步骤
- /// 旧根路径
- /// 新根路径
- /// 是否重置下步操作
- ///
- public Dir Clone(
- NextOpType? optype,
- string oldRootPath,
- string newRootPath,
- bool IsResetNextOpType = false
- )
- {
- var ndir = this.Clone(optype, IsResetNextOpType);
- ndir.ResetRootPath(oldRootPath, newRootPath);
- return ndir;
- }
-
- ///
- /// clone,不克隆文件
- ///
- ///
- ///
- ///
- ///
- public Dir Clone(NextOpType? optype = null, bool IsResetNextOpType = false)
- {
- var ndir = new Dir(this.FormatedPath, [], IsResetNextOpType ? optype : this.NextOp);
-
- var nchildren = this
- .Children.AsEnumerable()
- .Select(x =>
+ else
{
- if (x is File file)
+ //因为已经按照文件路径排过序了,当左侧文件名大于右侧,那么将根据右侧,添加一个删除diff
+ if (lreativePath.CompareTo(rreativePath) > 0)
{
- return new File(
- file.FormatedPath,
- file.MTime,
- IsResetNextOpType ? optype : file.NextOp
- ) as AFileOrDir;
+ rIndex_f++;
+ cDir.Children.Add(
+ new File
+ {
+ Path = r.FormatedPath,
+ MTime = r.MTime,
+ NextOp = NextOpType.Del
+ }
+ );
}
- else if (x is Dir dir)
+ //相反,根据左侧,添加一个新增diff
+ else
{
- return dir.Clone(optype, IsResetNextOpType);
+ lIndex_f++;
+ cDir.Children.Add(
+ new File
+ {
+ Path = l.FormatedPath.Replace(ldir.FormatedPath, rdir.FormatedPath),
+ MTime = l.MTime,
+ NextOp = NextOpType.Add
+ }
+ );
+ }
+ }
+ }
+
+ //文件夹的比较和文件类似,但是他会递归调用文件夹的diff函数,直至文件停止
+
+ while (true)
+ {
+ if (lIndex_d == lDirs.Count && rIndex_d == rDirs.Count)
+ {
+ break;
+ }
+ if (lIndex_d == lDirs.Count)
+ {
+ var er = rDirs[rIndex_d];
+ cDir.Children.Add(er.Clone(NextOpType.Del, true));
+ rIndex_d++;
+ continue;
+ }
+ if (rIndex_d == rDirs.Count)
+ {
+ var el = lDirs[lIndex_d];
+ cDir.Children.Add(
+ el.Clone(NextOpType.Add, true)
+ .ResetRootPath(ldir.FormatedPath, rdir.FormatedPath)
+ );
+ lIndex_d++;
+ continue;
+ }
+ var l = lDirs[lIndex_d];
+ var r = rDirs[rIndex_d];
+ var lreativePath = l.FormatedPath.Replace(ldir.FormatedPath, "");
+ var rreativePath = r.FormatedPath.Replace(rdir.FormatedPath, "");
+ if (lreativePath == rreativePath)
+ {
+ lIndex_d++;
+ rIndex_d++;
+ var rDir = l.Diff(r);
+ //而等于0,这表示此文件夹的内容没有变化
+ if (rDir.Children.Count != 0)
+ {
+ cDir.Children.Add(rDir);
+ }
+ }
+ else
+ {
+ //文件夹重命名将会触发整个文件夹的删除和新增操作,这里没有办法定位到操作是修改文件夹(?) 和git类似。
+ //潜在的问题是,修改文件夹名,此文件夹包含大量的文件,将触发大量操作。
+
+ if (lreativePath.CompareTo(rreativePath) > 0)
+ {
+ cDir.Children.Add(r.Clone(NextOpType.Del, true));
+ rIndex_d++;
}
else
{
- throw new Exception("cannot be here!");
+ cDir.Children.Add(
+ l.Clone(NextOpType.Add, true)
+ .ResetRootPath(ldir.FormatedPath, rdir.FormatedPath)
+ );
+ lIndex_d++;
}
- })
- .ToList();
- ndir.Children = nchildren;
-
- return ndir;
+ }
+ }
+ return cDir;
}
- ///
- /// 重设置根目录
- ///
- ///
- ///
- public void ResetRootPath(string oldPath, string newPath)
+ public static void WriteByThisInfo(this Dir thisDir, FileDirOpStra fileDirOp)
{
- this.FormatedPath = this.FormatedPath.Replace(oldPath, newPath);
- this.Children.ForEach(e =>
+ static void f(Dir dir, FileDirOpStra fileDirOp)
{
- if (e is File file)
+ dir.AccessCheck();
+ foreach (var child in dir.Children)
{
- file.FormatedPath = file.FormatedPath.Replace(oldPath, newPath);
+ if (child.Type == DirOrFile.Dir)
+ {
+ if (child is Dir childDir)
+ {
+ fileDirOp.DirCreate(childDir, false);
+ f(childDir, fileDirOp);
+ }
+ }
+ else
+ {
+ if (child is File childFile)
+ {
+ fileDirOp.FileCreate(child.FormatedPath, childFile.MTime);
+ }
+ else
+ {
+ throw new ArgumentException("child is not File!");
+ }
+ }
}
- else if (e is Dir dir)
- {
- dir.ResetRootPath(oldPath, newPath);
- }
- });
+ }
+ f(thisDir, fileDirOp);
}
- ///
- /// 文件夹合并
- ///
- /// 具体操作步骤
- /// 将要更新的内容
- /// 是否更新Object对象
- /// 是否更新文件目录树
- ///
- public void Combine(
+ public static void ExtractInfo(
+ this Dir thisDir,
+ List? cherryPicks = null,
+ List? exculdes = null
+ )
+ {
+ bool filter(string path)
+ {
+ if (cherryPicks != null)
+ {
+ return cherryPicks.Contains(path);
+ }
+
+ if (exculdes != null)
+ {
+ return !exculdes.Contains(path);
+ }
+ return true;
+ }
+
+ if (thisDir.Children.Count != 0)
+ {
+ throw new NotSupportedException("this dir is not empty.");
+ }
+ string[] files = Directory.GetFiles(thisDir.FormatedPath);
+ string[] dirs = Directory.GetDirectories(thisDir.FormatedPath);
+ foreach (var file in files)
+ {
+ if (filter(file))
+ {
+ thisDir.Children.Add(
+ new File { Path = file, MTime = System.IO.File.GetLastWriteTime($"{file}") }
+ );
+ }
+ }
+ foreach (var dir in dirs)
+ {
+ if (filter(dir))
+ {
+ var ndir = new Dir { Path = dir, Children = [] };
+ ndir.ExtractInfo();
+ thisDir.Children.Add(ndir);
+ }
+ }
+ }
+
+ public static void AddChild(this Dir thisDir, AFileOrDir child)
+ {
+ if (child.FormatedPath[..thisDir.FormatedPath.Length] != thisDir.FormatedPath)
+ {
+ throw new ArgumentException("their rootpath are not same!");
+ }
+ var filtedChildren = thisDir.Children.Where(x => x.Type == child.Type);
+
+ var mached = filtedChildren.Where(x => x.FormatedPath == child.FormatedPath);
+
+ if (mached.Any())
+ {
+ if (child is File)
+ {
+ throw new ArgumentException(
+ $"there are same path in the children:{child.FormatedPath}"
+ );
+ }
+ else if (child is Dir dir)
+ {
+ var tdir = mached.FirstOrDefault();
+ if (tdir is Dir ndir)
+ {
+ foreach (var d in dir.Children)
+ {
+ ndir.AddChild(d);
+ }
+ }
+ }
+ }
+ else
+ {
+ thisDir.Children.Add(child);
+ }
+ }
+
+ public static void Combine(
+ this Dir thisDir,
FileDirOpStra? fileDirOp,
Dir diffdir,
bool IsUpdateObject = true,
@@ -138,13 +373,13 @@ public class Dir(string path, List? children = null, NextOpType? nex
{
diffdir.AccessCheck();
}
- if (this.FormatedPath != diffdir.FormatedPath)
+ if (thisDir.FormatedPath != diffdir.FormatedPath)
{
throw new ArgumentException("their path is not same");
}
else
{
- var ldir = this;
+ var ldir = thisDir;
var rdir = diffdir;
foreach (var oc in diffdir.Children)
@@ -157,7 +392,9 @@ public class Dir(string path, List? children = null, NextOpType? nex
{
if (IsUpdateObject)
{
- ldir.AddChild(new File(rfile.FormatedPath, rfile.MTime));
+ ldir.AddChild(
+ new File { Path = rfile.FormatedPath, MTime = rfile.MTime }
+ );
}
if (IsUpdateDirFile)
{
@@ -247,153 +484,65 @@ public class Dir(string path, List? children = null, NextOpType? nex
}
}
- ///
- /// 合并两个文件夹,other不会发生改变,this将合并一个副本,这不会改变文件结构
- ///
- /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
- ///
- public void CombineJustObject(Dir other)
+ public static Dir Clone(
+ this Dir thisDir,
+ NextOpType? optype = null,
+ bool IsResetNextOpType = false
+ )
{
- Combine(null, other, true, false);
- }
-
- ///
- /// 合并两个文件夹,other不会发生改变,this将不会改变,而文件结构会改变
- ///
- /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
- ///
- public void CombineJustDirFile(FileDirOpStra fileDirOp, Dir diffDir)
- {
- Combine(fileDirOp, diffDir, false, true);
- }
-
- ///
- /// 添加子节点,根目录相同,才会被添加进去
- ///
- ///
- /// /
- protected void AddChild(AFileOrDir child)
- {
- if (child.FormatedPath[..this.FormatedPath.Length] != this.FormatedPath)
+ var ndir = new Dir
{
- throw new ArgumentException("their rootpath are not same!");
- }
- var filtedChildren = this.Children.Where(x => x.Type == child.Type);
+ Path = thisDir.FormatedPath,
+ Children = [],
+ NextOp = IsResetNextOpType ? optype : thisDir.NextOp
+ };
- var mached = filtedChildren.Where(x => x.FormatedPath == child.FormatedPath);
-
- if (mached.Any())
- {
- if (child is File)
+ var nchildren = thisDir
+ .Children.AsEnumerable()
+ .Select(x =>
{
- throw new ArgumentException(
- $"there are same path in the children:{child.FormatedPath}"
- );
- }
- else if (child is Dir dir)
- {
- var tdir = mached.FirstOrDefault();
- if (tdir is Dir ndir)
+ if (x is File file)
{
- foreach (var d in dir.Children)
- {
- ndir.AddChild(d);
- }
+ return new File
+ {
+ Path = file.FormatedPath,
+ MTime = file.MTime,
+ NextOp = IsResetNextOpType ? optype : file.NextOp
+ } as AFileOrDir;
}
- }
- }
- else
- {
- this.Children.Add(child);
- }
- }
-
- ///
- /// 从文件夹中提取信息
- ///
- /// 绝对路径,只包含的文件或者目录
- /// 绝对路径,排除的文件或目录
- ///
- public void ExtractInfo(List? cherryPicks = null, List? exculdes = null)
- {
- bool filter(string path)
- {
- if (cherryPicks != null)
- {
- return cherryPicks.Contains(path);
- }
-
- if (exculdes != null)
- {
- return !exculdes.Contains(path);
- }
- return true;
- }
-
- if (this.Children.Count != 0)
- {
- throw new NotSupportedException("this dir is not empty.");
- }
- string[] files = Directory.GetFiles(this.FormatedPath);
- string[] dirs = Directory.GetDirectories(this.FormatedPath);
- foreach (var file in files)
- {
- if (filter(file))
- {
- this.Children.Add(new File(file, System.IO.File.GetLastWriteTime($"{file}")));
- }
- }
- foreach (var dir in dirs)
- {
- if (filter(dir))
- {
- var ndir = new Dir(dir);
- ndir.ExtractInfo();
- this.Children.Add(ndir);
- }
- }
- }
-
- ///
- /// 写入目录文件树,首先必须定义写入文件的策略,此目录结构不包含文件内容,但有一个
- /// 文件的修改时间,是否修改文件的修改时间,需要定义文件的写入策略 WriteFileStrageFunc
- ///
- ///
- public void WriteByThisInfo(FileDirOpStra fileDirOp)
- {
- static void f(Dir dir, FileDirOpStra fileDirOp)
- {
- dir.AccessCheck();
- foreach (var child in dir.Children)
- {
- if (child.Type == DirOrFile.Dir)
+ else if (x is Dir dir)
{
- if (child is Dir childDir)
- {
- fileDirOp.DirCreate(childDir, false);
- f(childDir, fileDirOp);
- }
+ return dir.Clone(optype, IsResetNextOpType);
}
else
{
- if (child is File childFile)
- {
- fileDirOp.FileCreate(child.FormatedPath, childFile.MTime);
- }
- else
- {
- throw new ArgumentException("child is not File!");
- }
+ throw new Exception("cannot be here!");
}
- }
- }
- f(this, fileDirOp);
+ })
+ .ToList();
+ ndir.Children = nchildren;
+
+ return ndir;
}
- ///
- /// 校验文件夹和文件权限
- ///
- private void AccessCheck()
+ public static Dir ResetRootPath(this Dir thisDir, string oldPath, string newPath)
+ {
+ thisDir.FormatedPath = thisDir.FormatedPath.Replace(oldPath, newPath);
+ thisDir.Children.ForEach(e =>
+ {
+ if (e is File file)
+ {
+ file.FormatedPath = file.FormatedPath.Replace(oldPath, newPath);
+ }
+ else if (e is Dir dir)
+ {
+ dir.ResetRootPath(oldPath, newPath);
+ }
+ });
+ return thisDir;
+ }
+
+ public static void AccessCheck(this Dir thisDir)
{
//不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
return;
@@ -478,222 +627,248 @@ public class Dir(string path, List? children = null, NextOpType? nex
// }
//});
}
-
- ///
- /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有
- /// 节点都会打上标记
- /// 文件夹的 NextOp 只有新增和删除
- ///
- ///
- ///
- public Dir Diff(Dir other)
- {
- var ldir = this;
- var rdir = other;
- Dir? cDir = new(rdir.FormatedPath);
- //分别对文件和文件夹分组
- List lFiles = [];
- List rFiles = [];
- List lDirs = [];
- List rDirs = [];
- var lGroups = ldir.Children.GroupBy(x => x.Type);
- var rGroups = rdir.Children.GroupBy(x => x.Type);
- foreach (var g in lGroups)
- {
- if (g.Key == DirOrFile.Dir)
- {
- lDirs = g.AsEnumerable()
- .Select(n =>
- {
- if (n is Dir dir)
- {
- return dir;
- }
- throw new Exception("cannot be here");
- })
- .ToList();
- }
- else
- {
- lFiles = g.AsEnumerable()
- .Select(n =>
- {
- if (n is File file)
- {
- return file;
- }
- throw new Exception("cannot be here");
- })
- .ToList();
- }
- }
-
- foreach (var g in rGroups)
- {
- if (g.Key == DirOrFile.Dir)
- {
- rDirs = g.AsEnumerable()
- .Select(n =>
- {
- if (n is Dir dir)
- {
- return dir;
- }
- throw new Exception("cannot be here");
- })
- .ToList();
- }
- else
- {
- rFiles = g.AsEnumerable()
- .Select(n =>
- {
- if (n is File file)
- {
- return file;
- }
- throw new Exception("cannot be here");
- })
- .ToList();
- }
- }
-
- //排序,然后对比
- int lIndex_f = 0;
- int rIndex_f = 0;
- int lIndex_d = 0;
- int rIndex_d = 0;
- lFiles.Sort(Compare);
- rFiles.Sort(Compare);
- lDirs.Sort(Compare);
- rDirs.Sort(Compare);
- //对比文件
- while (true)
- {
- //当两个线性表都走到最后时,退出循环
- if (lIndex_f == lFiles.Count && rIndex_f == rFiles.Count)
- {
- break;
- }
- //左侧先到底,右侧都是将要删除的
- if (lIndex_f == lFiles.Count)
- {
- var er = rFiles[rIndex_f];
- cDir.Children.Add(new File(er.FormatedPath, er.MTime, NextOpType.Del));
- rIndex_f++;
- continue;
- }
- //右侧先到底,左侧都是要添加的
- if (rIndex_f == rFiles.Count)
- {
- var el = lFiles[lIndex_f];
-
- cDir.Children.Add(
- new File(
- el.FormatedPath.Replace(ldir.FormatedPath, rdir.FormatedPath),
- el.MTime,
- NextOpType.Add
- )
- );
- lIndex_f++;
- continue;
- }
- var l = lFiles[lIndex_f];
- var r = rFiles[rIndex_f];
- //将根路径差异抹平
- var lreativePath = l.FormatedPath.Replace(ldir.FormatedPath, "");
- var rreativePath = r.FormatedPath.Replace(rdir.FormatedPath, "");
- //两文件相同,对比文件修改时间,不同增加到diff内容
- if (lreativePath == rreativePath)
- {
- lIndex_f++;
- rIndex_f++;
- if (l.MTime != r.MTime)
- {
- cDir.Children.Add(new File(r.FormatedPath, l.MTime, NextOpType.Modify));
- }
- }
- else
- {
- //因为已经按照文件路径排过序了,当左侧文件名大于右侧,那么将根据右侧,添加一个删除diff
- if (lreativePath.CompareTo(rreativePath) > 0)
- {
- rIndex_f++;
- cDir.Children.Add(new File(r.FormatedPath, r.MTime, NextOpType.Del));
- }
- //相反,根据左侧,添加一个新增diff
- else
- {
- lIndex_f++;
- cDir.Children.Add(
- new File(
- l.FormatedPath.Replace(ldir.FormatedPath, rdir.FormatedPath),
- l.MTime,
- NextOpType.Add
- )
- );
- }
- }
- }
-
- //文件夹的比较和文件类似,但是他会递归调用文件夹的diff函数,直至文件停止
-
- while (true)
- {
- if (lIndex_d == lDirs.Count && rIndex_d == rDirs.Count)
- {
- break;
- }
- if (lIndex_d == lDirs.Count)
- {
- var er = rDirs[rIndex_d];
- cDir.Children.Add(er.Clone(NextOpType.Del, true));
- rIndex_d++;
- continue;
- }
- if (rIndex_d == rDirs.Count)
- {
- var el = lDirs[lIndex_d];
- cDir.Children.Add(
- el.Clone(NextOpType.Add, ldir.FormatedPath, rdir.FormatedPath, true)
- );
- lIndex_d++;
- continue;
- }
- var l = lDirs[lIndex_d];
- var r = rDirs[rIndex_d];
- var lreativePath = l.FormatedPath.Replace(ldir.FormatedPath, "");
- var rreativePath = r.FormatedPath.Replace(rdir.FormatedPath, "");
- if (lreativePath == rreativePath)
- {
- lIndex_d++;
- rIndex_d++;
- var rDir = l.Diff(r);
- //而等于0,这表示此文件夹的内容没有变化
- if (rDir.Children.Count != 0)
- {
- cDir.Children.Add(rDir);
- }
- }
- else
- {
- //文件夹重命名将会触发整个文件夹的删除和新增操作,这里没有办法定位到操作是修改文件夹(?) 和git类似。
- //潜在的问题是,修改文件夹名,此文件夹包含大量的文件,将触发大量操作。
-
- if (lreativePath.CompareTo(rreativePath) > 0)
- {
- cDir.Children.Add(r.Clone(NextOpType.Del, true));
- rIndex_d++;
- }
- else
- {
- cDir.Children.Add(
- l.Clone(NextOpType.Add, ldir.FormatedPath, rdir.FormatedPath, true)
- );
- lIndex_d++;
- }
- }
- }
- return cDir;
- }
}
+
+///
+/// 文件夹结构,它包含文件和文件夹
+///
+/// 绝对路径
+/// 子文件或文件夹
+// public class Dirxx(string path, List? children = null, NextOpType? nextOp = null)
+// : AFileOrDir(path, DirOrFile.Dir, nextOp)
+// {
+// public List Children { get; set; } = children ?? [];
+
+/* public override 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++)
+ {
+ if (!this.Children[i].IsEqual(otherDir.Children[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+} */
+
+///
+/// clone, 但是更改根目录
+///
+/// 操作步骤
+/// 旧根路径
+/// 新根路径
+/// 是否重置下步操作
+///
+// public Dir Clone(
+// NextOpType? optype,
+// string oldRootPath,
+// string newRootPath,
+// bool IsResetNextOpType = false
+// )
+// {
+// var ndir = this.Clone(optype, IsResetNextOpType);
+// ndir.ResetRootPath(oldRootPath, newRootPath);
+// return ndir;
+// }
+
+///
+/// clone,不克隆文件
+///
+///
+///
+///
+///
+// public Dir Clone(NextOpType? optype = null, bool IsResetNextOpType = false) { }
+
+///
+/// 重设置根目录
+///
+///
+///
+// public void ResetRootPath(string oldPath, string newPath)
+// {
+// this.FormatedPath = this.FormatedPath.Replace(oldPath, newPath);
+// this.Children.ForEach(e =>
+// {
+// if (e is File file)
+// {
+// file.FormatedPath = file.FormatedPath.Replace(oldPath, newPath);
+// }
+// else if (e is Dir dir)
+// {
+// dir.ResetRootPath(oldPath, newPath);
+// }
+// });
+// }
+
+///
+/// 文件夹合并
+///
+/// 具体操作步骤
+/// 将要更新的内容
+/// 是否更新Object对象
+/// 是否更新文件目录树
+///
+// public void Combine(
+// FileDirOpStra? fileDirOp,
+// Dir diffdir,
+// bool IsUpdateObject = true,
+// bool IsUpdateDirFile = false
+// ) { }
+
+// ///
+// /// 合并两个文件夹,other不会发生改变,this将合并一个副本,这不会改变文件结构
+// ///
+// /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
+// ///
+// public void CombineJustObject(Dir other)
+// {
+// Combine(null, other, true, false);
+// }
+
+// ///
+// /// 合并两个文件夹,other不会发生改变,this将不会改变,而文件结构会改变
+// ///
+// /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
+// ///
+// public void CombineJustDirFile(FileDirOpStra fileDirOp, Dir diffDir)
+// {
+// Combine(fileDirOp, diffDir, false, true);
+// }
+
+// ///
+// /// 添加子节点,根目录相同,才会被添加进去
+// ///
+// ///
+// /// /
+// protected void AddChild(AFileOrDir child) { }
+
+// ///
+// /// 从文件夹中提取信息
+// ///
+// /// 绝对路径,只包含的文件或者目录
+// /// 绝对路径,排除的文件或目录
+// ///
+
+
+// ///
+// /// 写入目录文件树,首先必须定义写入文件的策略,此目录结构不包含文件内容,但有一个
+// /// 文件的修改时间,是否修改文件的修改时间,需要定义文件的写入策略 WriteFileStrageFunc
+// ///
+// ///
+
+
+// ///
+// /// 校验文件夹和文件权限
+// ///
+// // private void AccessCheck()j
+// // {
+// //不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
+// // return;
+// //this.Children.ForEach(e =>
+// //{
+// // if (e is File file)
+// // {
+// // if (file.NextOp == null) { }
+// // else if (file.NextOp == NextOpType.Add)
+// // {
+// // if (
+// // !AccessWrapper.CheckDirAccess(
+// // Path.GetDirectoryName(file.FormatedPath)
+// // ?? throw new DirectoryNotFoundException(
+// // $"{file.FormatedPath} 此父路径不存在"
+// // ),
+// // [DirAcess.CreateFiles]
+// // )
+// // )
+// // {
+// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限创建文件");
+// // }
+// // }
+// // else if (file.NextOp == NextOpType.Modify)
+// // {
+// // if (
+// // !(
+// // AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete])
+// // && AccessWrapper.CheckDirAccess(
+// // Path.GetDirectoryName(file.FormatedPath)
+// // ?? throw new DirectoryNotFoundException(
+// // $"{file.FormatedPath} 此父路径不存在"
+// // ),
+// // [DirAcess.CreateFiles]
+// // )
+// // )
+// // )
+// // {
+// // throw new UnauthorizedAccessException(
+// // $"{file.FormatedPath} 无权限删除源文件或者创建新文件"
+// // );
+// // }
+// // }
+// // else if (file.NextOp == NextOpType.Del)
+// // {
+// // if (!AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete]))
+// // {
+// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限删除源文件");
+// // }
+// // }
+// // }
+// // else if (e is Dir dir)
+// // {
+// // if (dir.NextOp == null) { }
+// // else if (dir.NextOp == NextOpType.Add)
+// // {
+// // if (
+// // !AccessWrapper.CheckDirAccess(
+// // Path.GetDirectoryName(dir.FormatedPath)
+// // ?? throw new DirectoryNotFoundException(
+// // $"{dir.FormatedPath} 此父路径不存在"
+// // ),
+// // [DirAcess.CreateDirectories, DirAcess.CreateFiles]
+// // )
+// // )
+// // {
+// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限创建文件夹或者文件");
+// // }
+// // }
+// // else if (dir.NextOp == NextOpType.Del)
+// // {
+// // if (!AccessWrapper.CheckDirAccess(dir.FormatedPath, [DirAcess.Delete]))
+// // {
+// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限删除文件夹");
+// // }
+// // else
+// // {
+// // //校验是否拥有子文件或者文件夹的删除权限,
+// // dir.AccessCheck();
+// // }
+// // }
+// // }
+// //});
+// // }
+
+// ///
+// /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有
+// /// 节点都会打上标记
+// /// 文件夹的 NextOp 只有新增和删除
+// ///
+// ///
+// ///
+// }
diff --git a/Server/Common/FileDirBase.cs b/Server/Common/FileDirBase.cs
index bd83726..847df13 100644
--- a/Server/Common/FileDirBase.cs
+++ b/Server/Common/FileDirBase.cs
@@ -13,21 +13,17 @@ public enum NextOpType
Del = 2
}
-public abstract class AFileOrDir(
- string path,
- DirOrFile type = DirOrFile.File,
- NextOpType? nextOp = null
-)
+public abstract class AFileOrDir
{
- public DirOrFile Type { get; set; } = type;
- public NextOpType? NextOp { get; set; } = nextOp;
+ public DirOrFile Type { get; set; }
+ public NextOpType? NextOp { get; set; }
// private string Path = path;
///
/// 全部为绝对路径... 占用资源会大一点,但是完全OK
///
///
- private string Path = path;
+ public required string Path { get; set; }
///
/// 相当于Path 包装,天杀的windows在路径字符串中使用两种分隔符,“/” 和“\”,这导致,即使两个字符串不相同,也可能是同一个路径。现在把它们统一起来
@@ -55,10 +51,13 @@ public abstract class AFileOrDir(
///
/// 绝对路径
/// 文件的修改时间/
-public class File(string path, DateTime mtime, NextOpType? nextOp = null)
- : AFileOrDir(path, DirOrFile.File, nextOp)
+public class File : AFileOrDir
{
- public DateTime MTime { get; set; } = mtime;
+ public File()
+ {
+ Type = DirOrFile.File;
+ }
+ public required DateTime MTime { get; set; }
public override bool IsEqual(AFileOrDir other)
{
@@ -77,3 +76,41 @@ public class File(string path, DateTime mtime, NextOpType? nextOp = null)
}
}
}
+
+public class Dir : AFileOrDir
+{
+ public Dir()
+ {
+ Type = DirOrFile.Dir;
+ }
+ public required List Children { get; set; }
+
+ public override 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++)
+ {
+ if (!this.Children[i].IsEqual(otherDir.Children[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+}
diff --git a/Server/LocalServer/StateHelper.cs b/Server/LocalServer/StateHelper.cs
index 5c105c8..c1a5658 100644
--- a/Server/LocalServer/StateHelper.cs
+++ b/Server/LocalServer/StateHelper.cs
@@ -202,7 +202,11 @@ public class DiffFileAndPackHelper(LocalSyncServer context)
//提取本地文件的信息
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
{
- e.LocalDirInfo = new Dir(Context.NotNullSyncConfig.LocalRootPath + e.DirPath);
+ e.LocalDirInfo = new Dir
+ {
+ Path = Context.NotNullSyncConfig.LocalRootPath + e.DirPath,
+ Children = []
+ };
e.LocalDirInfo.ExtractInfo(e.CherryPicks, e.Excludes);
});
//将配置信息发送到remoteServer
diff --git a/Server/RemoteServer/StateHelper.cs b/Server/RemoteServer/StateHelper.cs
index 43f33ce..036eb32 100644
--- a/Server/RemoteServer/StateHelper.cs
+++ b/Server/RemoteServer/StateHelper.cs
@@ -204,7 +204,7 @@ public class FinallyPublishHelper(RemoteSyncServer context)
{
if (e.RemoteDirInfo != null && e.DiffDirInfo != null)
{
- e.RemoteDirInfo.CombineJustDirFile(DirFileOp, e.DiffDirInfo);
+ e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo,false,true);
}
});
diff --git a/Server/ServerTest/DirFileOpTest.cs b/Server/ServerTest/DirFileOpTest.cs
index 4776d29..4a75521 100644
--- a/Server/ServerTest/DirFileOpTest.cs
+++ b/Server/ServerTest/DirFileOpTest.cs
@@ -1,8 +1,9 @@
using Common;
+using Newtonsoft.Json;
using XUnit.Project.Attributes;
-/*using Newtonsoft.Json;*/
namespace ServerTest;
+
///
/// xUnit将会对每个测试方法创建一个测试上下文,IClassFixture可以用来创建类中共享测试上下文,
///
@@ -35,10 +36,10 @@ public class DirFileOpTest : IDisposable
{
filesSeed.NewDir.WriteByThisInfo(filesSeed.fileDirOp);
filesSeed.OldDir.WriteByThisInfo(filesSeed.fileDirOp);
- Dir nnd = new(filesSeed.NewDir.FormatedPath);
+ Dir nnd = new() { Path = filesSeed.NewDir.FormatedPath, Children = [] };
nnd.ExtractInfo();
Assert.True(nnd.IsEqual(filesSeed.NewDir), "新文件提取文件夹的信息与写入信息不一致!");
- Dir nod = new(filesSeed.OldDir.FormatedPath);
+ Dir nod = new() { Path = filesSeed.OldDir.FormatedPath, Children = [] };
nod.ExtractInfo();
Assert.True(nod.IsEqual(filesSeed.OldDir), "旧提取文件夹的信息与写入信息不一致!");
}
@@ -54,7 +55,7 @@ public class DirFileOpTest : IDisposable
// Console.WriteLine(cDDir.Children.Count);
//Assert.True(IsSuccess);
- /*var str = JsonConvert.SerializeObject(cDDir);*/
+ // var str = JsonConvert.SerializeObject(cDDir);
Assert.True(filesSeed.DiffDir.IsEqual(cDDir), "文件对比结果错误!");
}
@@ -65,8 +66,8 @@ public class DirFileOpTest : IDisposable
public void SyncFileDir()
{
filesSeed.OldDir.WriteByThisInfo(filesSeed.fileDirOp);
- filesSeed.OldDir.CombineJustDirFile(filesSeed.fileDirOp, filesSeed.DiffDir);
- Dir oldSync = new(filesSeed.OldDir.FormatedPath);
+ filesSeed.OldDir.Combine(filesSeed.fileDirOp, filesSeed.DiffDir, false, true);
+ Dir oldSync = new() { Path = filesSeed.OldDir.FormatedPath, Children = [] };
oldSync.ExtractInfo();
oldSync.ResetRootPath(filesSeed.OldDir.FormatedPath, filesSeed.NewDir.FormatedPath);
Assert.True(oldSync.IsEqual(filesSeed.NewDir), "文件夹同步后信息保持不一致!");
@@ -78,7 +79,7 @@ public class DirFileOpTest : IDisposable
[Fact, TestPriority(3)]
public void DirsCombine()
{
- filesSeed.OldDir.CombineJustObject(filesSeed.DiffDir);
+ filesSeed.OldDir.Combine(null, filesSeed.DiffDir);
//Assert.False(filesSeed.NewDir.IsEqual(filesSeed.OldDir));
filesSeed.OldDir.ResetRootPath("OldDir", "NewDir");
// Console.WriteLine(filesSeed.OldDir.Path);
diff --git a/Server/ServerTest/FilesSeed.cs b/Server/ServerTest/FilesSeed.cs
index 24ee286..3a48e59 100644
--- a/Server/ServerTest/FilesSeed.cs
+++ b/Server/ServerTest/FilesSeed.cs
@@ -10,168 +10,263 @@ public class FilesSeed : IDisposable
// string TestPath = Path.Combine(Directory.GetCurrentDirectory(), "../../..");
DateTime NewTime = DateTime.Now.AddSeconds(-99);
DateTime OldTime = NewTime.AddSeconds(-20);
- NewDir = new Dir(
- TestPath + "/NewDir",
+ NewDir = new Dir
+ {
+ Path = TestPath + "/NewDir",
+ Children =
[
- new Dir($"{TestPath}/NewDir/0"),
- new Dir(
- $"{TestPath}/NewDir/1",
- [new Common.File($"{TestPath}/NewDir/1/1.txt", NewTime)]
- ),
- new Dir(
- $"{TestPath}/NewDir/2",
+ new Dir { Path = $"{TestPath}/NewDir/0", Children = [] },
+ new Dir
+ {
+ Path = $"{TestPath}/NewDir/1",
+ Children =
[
- new Common.File($"{TestPath}/NewDir/2/2.txt", NewTime),
- new Dir(
- $"{TestPath}/NewDir/2/2_1",
- [
- new Common.File($"{TestPath}/NewDir/2/2_1/1.txt", NewTime),
- new Common.File($"{TestPath}/NewDir/2/2_1/2.txt", NewTime),
- ]
- ),
- new Dir(
- $"{TestPath}/NewDir/2/2_2",
- [
- new Common.File($"{TestPath}/NewDir/2/2_2/1.txt", NewTime),
- new Common.File($"{TestPath}/NewDir/2/2_2/2.txt", NewTime),
- new Dir(
- $"{TestPath}/NewDir/2/2_2/2_3",
- [
- new Common.File(
- $"{TestPath}/NewDir/2/2_2/2_3/1.txt",
- NewTime
- ),
- ]
- ),
- ]
- )
+ new Common.File { Path = $"{TestPath}/NewDir/1/1.txt", MTime = NewTime }
]
- ),
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/NewDir/2",
+ Children =
+ [
+ new Common.File { Path = $"{TestPath}/NewDir/2/2.txt", MTime = NewTime },
+ new Dir
+ {
+ Path = $"{TestPath}/NewDir/2/2_1",
+ Children =
+ [
+ new Common.File
+ {
+ Path = $"{TestPath}/NewDir/2/2_1/1.txt",
+ MTime = NewTime
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/NewDir/2/2_1/2.txt",
+ MTime = NewTime
+ },
+ ]
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/NewDir/2/2_2",
+ Children =
+ [
+ new Common.File
+ {
+ Path = $"{TestPath}/NewDir/2/2_2/1.txt",
+ MTime = NewTime
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/NewDir/2/2_2/2.txt",
+ MTime = NewTime
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/NewDir/2/2_2/2_3",
+ Children =
+ [
+ new Common.File
+ {
+ Path = $"{TestPath}/NewDir/2/2_2/2_3/1.txt",
+ MTime = NewTime
+ },
+ ]
+ },
+ ]
+ }
+ ]
+ },
]
- );
- DiffDir = new Dir(
- $"{TestPath}/OldDir",
+ };
+ DiffDir = new Dir
+ {
+ Path = $"{TestPath}/OldDir",
+ Children =
[
- new Dir(
- $"{TestPath}/OldDir/1",
- [new Common.File($"{TestPath}/OldDir/1/2_D.txt", NewTime, NextOpType.Del),]
- ),
- new Dir(
- $"{TestPath}/OldDir/2",
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/1",
+ Children =
+ [
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/1/2_D.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Del
+ },
+ ]
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2",
+ Children =
[
// 将要添加
- new Common.File($"{TestPath}/OldDir/2/2.txt", NewTime, NextOpType.Add),
- new Dir(
- $"{TestPath}/OldDir/2/2_1",
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Add
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_1",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_1/2.txt",
- NewTime,
- NextOpType.Modify
- ),
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_1/2.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Modify
+ },
]
- ),
- new Dir(
- $"{TestPath}/OldDir/2/2_2_M",
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_2_M/1.txt",
- OldTime,
- NextOpType.Del
- ),
- new Common.File(
- $"{TestPath}/OldDir/2/2_2_M/2.txt",
- OldTime,
- NextOpType.Del
- ),
- new Dir(
- $"{TestPath}/OldDir/2/2_2_M/2_3",
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/1.txt",
+ MTime = OldTime,
+ NextOp = NextOpType.Del
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2.txt",
+ MTime = OldTime,
+ NextOp = NextOpType.Del
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2_3",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_2_M/2_3/1.txt",
- OldTime,
- NextOpType.Del
- ),
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2_3/1.txt",
+ MTime = OldTime,
+ NextOp = NextOpType.Del
+ },
],
- NextOpType.Del
- ),
+ NextOp = NextOpType.Del
+ },
],
- NextOpType.Del
- ),
- new Dir(
- $"{TestPath}/OldDir/2/2_2",
+ NextOp = NextOpType.Del
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_2/1.txt",
- NewTime,
- NextOpType.Add
- ),
- new Common.File(
- $"{TestPath}/OldDir/2/2_2/2.txt",
- NewTime,
- NextOpType.Add
- ),
- new Dir(
- $"{TestPath}/OldDir/2/2_2/2_3",
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2/1.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Add
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2/2.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Add
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2/2_3",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_2/2_3/1.txt",
- NewTime,
- NextOpType.Add
- ),
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2/2_3/1.txt",
+ MTime = NewTime,
+ NextOp = NextOpType.Add
+ },
],
- NextOpType.Add
- ),
+ NextOp = NextOpType.Add
+ },
],
- NextOpType.Add
- )
+ NextOp = NextOpType.Add
+ }
]
- ),
+ },
]
- );
- OldDir = new Dir(
- $"{TestPath}/OldDir",
+ };
+ OldDir = new Dir
+ {
+ Path = $"{TestPath}/OldDir",
+ Children =
[
- new Dir($"{TestPath}/OldDir/0"),
- new Dir(
- $"{TestPath}/OldDir/1",
+ new Dir { Path = $"{TestPath}/OldDir/0", Children = [] },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/1",
+ Children =
[
//不做修改
- new Common.File($"{TestPath}/OldDir/1/1.txt", NewTime),
+ new Common.File { Path = $"{TestPath}/OldDir/1/1.txt", MTime = NewTime },
//将要删除
- new Common.File($"{TestPath}/OldDir/1/2_D.txt", NewTime),
+ new Common.File { Path = $"{TestPath}/OldDir/1/2_D.txt", MTime = NewTime },
]
- ),
- new Dir(
- $"{TestPath}/OldDir/2",
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2",
+ Children =
[
- new Dir(
- $"{TestPath}/OldDir/2/2_1",
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_1",
+ Children =
[
- new Common.File($"{TestPath}/OldDir/2/2_1/1.txt", NewTime),
- new Common.File($"{TestPath}/OldDir/2/2_1/2.txt", OldTime),
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_1/1.txt",
+ MTime = NewTime
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_1/2.txt",
+ MTime = OldTime
+ },
]
- ),
- new Dir(
- $"{TestPath}/OldDir/2/2_2_M",
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M",
+ Children =
[
- new Common.File($"{TestPath}/OldDir/2/2_2_M/1.txt", OldTime),
- new Common.File($"{TestPath}/OldDir/2/2_2_M/2.txt", OldTime),
- new Dir(
- $"{TestPath}/OldDir/2/2_2_M/2_3",
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/1.txt",
+ MTime = OldTime
+ },
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2.txt",
+ MTime = OldTime
+ },
+ new Dir
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2_3",
+ Children =
[
- new Common.File(
- $"{TestPath}/OldDir/2/2_2_M/2_3/1.txt",
- OldTime
- ),
+ new Common.File
+ {
+ Path = $"{TestPath}/OldDir/2/2_2_M/2_3/1.txt",
+ MTime = OldTime
+ },
]
- ),
+ },
]
- )
+ }
]
- ),
+ },
]
- );
+ };
fileDirOp = new SimpleFileDirOp();
}
diff --git a/Server/ServerTest/PipeTest.cs b/Server/ServerTest/PipeTest.cs
index 5fbbc82..fc9673f 100644
--- a/Server/ServerTest/PipeTest.cs
+++ b/Server/ServerTest/PipeTest.cs
@@ -13,46 +13,46 @@ public class PipeTest
[Fact]
public async void TestCase()
{
- var p1 = new TestPipe(false, "1");
- var x = Task.Run(async () =>
- {
- var rs = p1.Work(
- (byte[] b) =>
- {
- Console.WriteLine(b);
- return true;
- }
- );
- await foreach (var r in rs)
- {
- Console.WriteLine(r);
- }
- });
- //await p1.Close("sdf");
- //await x;
- var p2 = new TestPipe(false, "2");
- p1.Other = p2;
- p2.Other = p1;
- var p3 = new TestPipe(true, "3");
- var p4 = new TestPipe(true, "4");
- p3.Other = p4;
- p4.Other = p3;
- RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")];
- var lf = new LocalSyncServerFactory();
- lf.CreateLocalSyncServer(p2, "Test", p3);
- var rf = new RemoteSyncServerFactory();
- rf.CreateRemoteSyncServer(p4, "Test");
- var starter = new SyncMsg
- {
- Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
- Type = SyncMsgType.General,
- Step = SyncProcessStep.Connect
- };
- await p1.SendMsg(starter);
- await x;
- if (p1.ErrResult != null)
- {
- Assert.Fail(p1.ErrResult);
- }
+ // var p1 = new TestPipe(false, "1");
+ // var x = Task.Run(async () =>
+ // {
+ // var rs = p1.Work(
+ // (byte[] b) =>
+ // {
+ // Console.WriteLine(b);
+ // return true;
+ // }
+ // );
+ // await foreach (var r in rs)
+ // {
+ // Console.WriteLine(r);
+ // }
+ // });
+ // //await p1.Close("sdf");
+ // //await x;
+ // var p2 = new TestPipe(false, "2");
+ // p1.Other = p2;
+ // p2.Other = p1;
+ // var p3 = new TestPipe(true, "3");
+ // var p4 = new TestPipe(true, "4");
+ // p3.Other = p4;
+ // p4.Other = p3;
+ // RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")];
+ // var lf = new LocalSyncServerFactory();
+ // lf.CreateLocalSyncServer(p2, "Test", p3);
+ // var rf = new RemoteSyncServerFactory();
+ // rf.CreateRemoteSyncServer(p4, "Test");
+ // var starter = new SyncMsg
+ // {
+ // Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
+ // Type = SyncMsgType.General,
+ // Step = SyncProcessStep.Connect
+ // };
+ // await p1.SendMsg(starter);
+ // await x;
+ // if (p1.ErrResult != null)
+ // {
+ // Assert.Fail(p1.ErrResult);
+ // }
}
}