/// <summary> /// create tree path from path text /// </summary> /// <param name="path"></param> /// <param name="lastDir">last dir in path</param> /// <returns></returns> private List <DirTree> GetAbsoluteTreePath(string path, out DirTree lastDir) { List <DirTree> treePath = new List <DirTree>() { Root }; DirTree dir = Root; if (path != "") { string[] dirs = path.Split('\\'); for (int i = 1; i < dirs.Length; i++) { dir = dir._dirs.FirstOrDefault(x => x.Info.Name == dirs[i]); if (dir == null) { lastDir = null; return(null); } treePath.Add(dir); } } lastDir = dir; return(treePath); }
/// <summary> /// fetch changes of files and subdirs for Two-Way sync recursively /// </summary> /// <param name="dirTree">dir tree</param> /// <param name="interruptChecker">is called when the cancellation or pause request should be checked in order to handel them</param> /// <param name="parentCompareResult">compare-result of parent | null in root</param> public static void FetchChangesInDirRecursively_TwoWay(DirTree dirTree, Func <bool> interruptChecker, TwoWayCompareResult parentCompareResult) { interruptChecker(); TwoWayCompareResult result = parentCompareResult; foreach (DirTree childDir in dirTree.Dirs) { if (result == null) { result = DetectDirChange_TwoWay(childDir.Info); } if (result != null) { new SyncDirExecutionInfo(childDir.Info.SyncDirInfo, result.Direction, result.Remove); } FetchChangesInDirRecursively_TwoWay(childDir, interruptChecker, result); } foreach (MyFileInfo file in dirTree.Files) { if (result == null) { DoFileComparison_TwoWay(file.SyncFileInfo, interruptChecker); } else { file.Size = new Delimon.Win32.IO.FileInfo(result.Direction == SyncDirection.To2 ? file.SyncFileInfo.AbsolutePath1 : file.SyncFileInfo.AbsolutePath2).Length; //load file size new SyncFileExecutionInfo(file.SyncFileInfo, result.Direction, result.Remove); } } }
/// <summary> /// create DirTree /// </summary> /// <param name="info">directory info</param> /// <param name="parent">parent dir | null if root</param> /// <param name="root">this if null</param> public DirTree(MyDirInfo info, DirTree parent, DirTree root) { _info = info; _parent = parent; if (root == null) _root = this; else _root = root; }
public List <DirTree> AddDir(MyDirInfo newDir) { DirTree dt = new DirTree(newDir, this, Root); DirTree parentDir; newDir.DirTreeInfo = dt; newDir.TreePath = GetAbsoluteTreePath(newDir.Path, out parentDir); parentDir._dirs.Add(dt); return(newDir.TreePath); }
public static IEnumerable<MyFileInfo> GetFiles(DirTree dt) { foreach (DirTree subdir in dt.Dirs) foreach (var f in GetFiles(subdir)) yield return f; foreach (MyFileInfo f in dt.Files) { yield return f; } }
/// <summary> /// delete directories /// </summary> /// <param name="dirTree">directory tree</param> /// <returns></returns> private void RemoveFolders(DirTree dirTree) { foreach (DirTree childDir in dirTree.Dirs) { RemoveFolders(childDir); if (childDir.Info.SyncDirInfo?.SyncDirExecutionInfo != null && childDir.Info.SyncDirInfo.SyncDirExecutionInfo.Remove) { Helper.DeleteFolder(childDir.Info.SyncDirInfo.SyncDirExecutionInfo, CheckInterrupt1); } } }
/// <summary> /// create DirTree /// </summary> /// <param name="info">directory info</param> /// <param name="parent">parent dir | null if root</param> /// <param name="root">this if null</param> public DirTree(MyDirInfo info, DirTree parent, DirTree root) { _info = info; _parent = parent; if (root == null) { _root = this; } else { _root = root; } }
public static IEnumerable <MyFileInfo> GetFiles(DirTree dt) { foreach (DirTree subdir in dt.Dirs) { foreach (var f in GetFiles(subdir)) { yield return(f); } } foreach (MyFileInfo f in dt.Files) { yield return(f); } }
/// <summary> /// apply file changes to all synchronisation files /// </summary> /// <param name="dirTree">directory tree</param> /// <returns></returns> private void DoApplyFileChanges(DirTree dirTree) { foreach (DirTree childDir in dirTree.Dirs) { DoApplyFileChanges(childDir); } foreach (MyFileInfo file in dirTree.Files) { if (file.SyncFileInfo?.SyncFileExecutionInfo != null) { Helper.ApplyFileChange(file.SyncFileInfo.SyncFileExecutionInfo, CheckInterrupt1); } } }
/// <summary> /// create SyncInfo /// </summary> /// <param name="link">link data (will be copied not referenced)</param> public SyncInfo(SyncLink link) { Link = link; Time = new TimeMeasurement(this); Files = new FilesInfo(this); Dirs = new DirsInfo(this); Paused = false; SyncDirExecutionInfos = new List<SyncDirExecutionInfo>(); SyncFileExecutionInfos = new List<SyncFileExecutionInfo>(); ConflictInfos = new List<ElementConflictInfo>(); LogStack = new Stack<LogMessage>(); MyDirInfo rootDir = new MyDirInfo("\\", ""); SyncDirInfo sdi = new SyncDirInfo(this, rootDir, false); DirTree = new DirTree(rootDir, null, null); Status = SyncStatus.DetectingChanges; }
/// <summary> /// create SyncInfo /// </summary> /// <param name="link">link data (will be copied not referenced)</param> public SyncInfo(SyncLink link) { Link = link; Time = new TimeMeasurement(this); Files = new FilesInfo(this); Dirs = new DirsInfo(this); Paused = false; SyncDirExecutionInfos = new List <SyncDirExecutionInfo>(); SyncFileExecutionInfos = new List <SyncFileExecutionInfo>(); ConflictInfos = new List <ElementConflictInfo>(); LogStack = new Stack <LogMessage>(); MyDirInfo rootDir = new MyDirInfo("\\", ""); SyncDirInfo sdi = new SyncDirInfo(this, rootDir, false); DirTree = new DirTree(rootDir, null, null); Status = SyncStatus.DetectingChanges; }
/// <summary> /// fetch changes of files and subdirs for Two-Way sync recursively /// </summary> /// <param name="dirTree">dir tree</param> /// <param name="interruptChecker">is called when the cancellation or pause request should be checked in order to handel them</param> /// <param name="parentCompareResult">compare-result of parent | null in root</param> public static void FetchChangesInDirRecursively_TwoWay(DirTree dirTree, Func<bool> interruptChecker, TwoWayCompareResult parentCompareResult) { interruptChecker(); TwoWayCompareResult result = parentCompareResult; foreach (DirTree childDir in dirTree.Dirs) { if (result == null) result = DetectDirChange_TwoWay(childDir.Info); if(result != null) new SyncDirExecutionInfo(childDir.Info.SyncDirInfo, result.Direction, result.Remove); FetchChangesInDirRecursively_TwoWay(childDir, interruptChecker, result); } foreach (MyFileInfo file in dirTree.Files) { if(result == null) { DoFileComparison_TwoWay(file.SyncFileInfo, interruptChecker); } else { file.Size = new Delimon.Win32.IO.FileInfo(result.Direction == SyncDirection.To2 ? file.SyncFileInfo.AbsolutePath1 : file.SyncFileInfo.AbsolutePath2).Length; //load file size new SyncFileExecutionInfo(file.SyncFileInfo, result.Direction, result.Remove); } } }
/// <summary> /// delete directories /// </summary> /// <param name="dirTree">directory tree</param> /// <returns></returns> private void RemoveFolders(DirTree dirTree) { foreach(DirTree childDir in dirTree.Dirs) { RemoveFolders(childDir); if(childDir.Info.SyncDirInfo?.SyncDirExecutionInfo != null && childDir.Info.SyncDirInfo.SyncDirExecutionInfo.Remove) Helper.DeleteFolder(childDir.Info.SyncDirInfo.SyncDirExecutionInfo, CheckInterrupt1); } }
public List<DirTree> AddDir(MyDirInfo newDir) { DirTree dt = new DirTree(newDir, this, Root); DirTree parentDir; newDir.DirTreeInfo = dt; newDir.TreePath = GetAbsoluteTreePath(newDir.Path, out parentDir); parentDir._dirs.Add(dt); return newDir.TreePath; }
public void SyncElementStatusChanged(SyncElementInfo sei) { bool isFile = typeof(SyncFileInfo) == sei.GetType(); switch (sei.SyncStatus) { case SyncElementStatus.ElementFound: if (isFile) { _filesFoundCount++; DirTree.AddFile((MyFileInfo)sei.ElementInfo); } else { _dirsFoundCount++; DirTree.AddDir((MyDirInfo)sei.ElementInfo); } break; case SyncElementStatus.ChangeDetectingStarted: break; case SyncElementStatus.NoChangeFound: break; case SyncElementStatus.ChangeFound: if (isFile) { SyncFileExecutionInfos.Add((SyncFileExecutionInfo)sei.SyncExecutionInfo); if (sei.SyncExecutionInfo.Remove) { _filesToRemoveCount++; _filesTotalSizeToRemove += ((MyFileInfo)sei.ElementInfo).Size; } else { _filesToCopyCount++; _filesTotalSizeToCopy += ((MyFileInfo)sei.ElementInfo).Size; } } else { SyncDirExecutionInfos.Add((SyncDirExecutionInfo)sei.SyncExecutionInfo); if (sei.SyncExecutionInfo.Remove) { _dirsToRemoveCount++; } else { _dirsToCreateCount++; } } break; case SyncElementStatus.ChangeApplied: if (isFile) { if (sei.SyncExecutionInfo.Remove) { _fileSizeRemoved += ((SyncFileInfo)sei).FileInfo.Size; _filesRemovedCount++; } else { _fileSizeCopied += ((SyncFileInfo)sei).FileInfo.Size; _filesCopiedCount++; } } else { if (sei.SyncExecutionInfo.Remove) { _dirsRemovedCount++; } else { _dirsCreatedCount++; } } break; case SyncElementStatus.Conflicted: ConflictInfos.Add(sei.ConflictInfo); break; } _listener?.OnSyncElementStatusChanged(sei); }
/// <summary> /// create tree path from path text /// </summary> /// <param name="path"></param> /// <param name="lastDir">last dir in path</param> /// <returns></returns> private List<DirTree> GetAbsoluteTreePath(string path, out DirTree lastDir) { List<DirTree> treePath = new List<DirTree>() { Root }; DirTree dir = Root; if (path != "") { string[] dirs = path.Split('\\'); for (int i = 1; i < dirs.Length; i++) { dir = dir._dirs.FirstOrDefault(x => x.Info.Name == dirs[i]); if (dir == null) { lastDir = null; return null; } treePath.Add(dir); } } lastDir = dir; return treePath; }
/// <summary> /// apply file changes to all synchronisation files /// </summary> /// <param name="dirTree">directory tree</param> /// <returns></returns> private void DoApplyFileChanges(DirTree dirTree) { foreach (DirTree childDir in dirTree.Dirs) DoApplyFileChanges(childDir); foreach(MyFileInfo file in dirTree.Files) { if (file.SyncFileInfo?.SyncFileExecutionInfo != null) Helper.ApplyFileChange(file.SyncFileInfo.SyncFileExecutionInfo, CheckInterrupt1); } }
/// <summary> /// execute synchronisation /// </summary> public void ExecuteSync() { _ts = new CancellationTokenSource(); _ct = _ts.Token; if (!Delimon.Win32.IO.Directory.Exists(_si.Link.Path1) || !Delimon.Win32.IO.Directory.Exists(_si.Link.Path2)) { throw new DirectoryNotFoundException(); } _si.Status = SyncStatus.FetchingElements; if (_si.Link.Direction == SyncDirection.To1) { Helper.FetchFilesInDirRecursively_OneWay(_si.Link.Path2, _si.Link.Path1, new MyDirInfo("", ""), _si, (sfi) => { }, CheckInterrupt1); _si.Status = SyncStatus.DetectingChanges; foreach (MyFileInfo fi in DirTree.GetFiles(_si.DirTree)) { Helper.DoFileComparison_OneWay(_si.Link.Path2, _si.Link.Path1, fi.SyncFileInfo, CheckInterrupt1); } Helper.GetRemoveInfosOfDirRecursively_OneWay(_si.Link.Path2, _si.Link.Path1, new MyDirInfo("", ""), _si, CheckInterrupt1); } else if (_si.Link.Direction == SyncDirection.To2) { Helper.FetchFilesInDirRecursively_OneWay(_si.Link.Path1, _si.Link.Path2, new MyDirInfo("", ""), _si, (sfi) => { }, CheckInterrupt1); _si.Status = SyncStatus.DetectingChanges; foreach (MyFileInfo fi in DirTree.GetFiles(_si.DirTree)) { Helper.DoFileComparison_OneWay(_si.Link.Path2, _si.Link.Path1, fi.SyncFileInfo, CheckInterrupt1); } Helper.GetRemoveInfosOfDirRecursively_OneWay(_si.Link.Path1, _si.Link.Path2, new MyDirInfo("", ""), _si, CheckInterrupt1); } else if (_si.Link.Direction == SyncDirection.TwoWay) { Helper.FetchElementsInDirRecursively_TwoWay(new MyDirInfo("", ""), _si, (sfi) => { }, CheckInterrupt1); _si.Status = SyncStatus.DetectingChanges; Helper.FetchChangesInDirRecursively_TwoWay(_si.DirTree, CheckInterrupt1, null); } _si.Status = SyncStatus.CreatingFolders; CreateFolders(_si.DirTree); _si.Status = SyncStatus.ApplyingFileChanges; DoApplyFileChanges(_si.DirTree); _si.Status = SyncStatus.RemoveDirs; RemoveFolders(_si.DirTree); }
private void BuildTreeRecursively(TreeNodeCollection nodes, DirTree dirTree) { foreach(MyFileInfo file in dirTree.Files) { AddFileTreeNode(nodes, file); } foreach (DirTree dir in dirTree.Dirs) { TreeNode tn = AddDirTreeNode(nodes, dir.Info); BuildTreeRecursively(tn.Nodes, dir); } }
/// <summary> /// build base treenodes in treeView /// </summary> /// <param name="dirTree"></param> private void BuildTreeBase(DirTree dirTree) { foreach (DirTree dir in dirTree.Dirs) { dir.Info.DirTreeViewNode = new SyncDirTreeViewNode(dir.Info); treeView1.Nodes.Add(dir.Info.DirTreeViewNode); } foreach (MyFileInfo file in dirTree.Files) { file.FileTreeViewNode = new SyncFileTreeViewNode(file); treeView1.Nodes.Add(file.FileTreeViewNode); } }