private void _SynchronizeFolder(String Path, double StepFrom = 0.0, double StepTo = 1.0) { //Console.WriteLine("------------{0}/{1}", StepFrom, StepTo); Canceling = false; CallStep(StepFrom, String.Format(SynchronizingFormat, Path)); var SourceFiles = this.SourceFileSystem .FindFiles(FileSystem.CombinePath(SourcePath, Path)) .ToDictionary(FileSystemEntry => FileSystemEntry.Name) ; var DestinationFiles = this.DestinationFileSystem .FindFiles(FileSystem.CombinePath(DestinationPath, Path)) .ToDictionary(FileSystemEntry => FileSystemEntry.Name) ; var FilesToRemove = new LinkedList <FileSystemEntry>(); var FilesToUpdate = new LinkedList <FileSystemEntry>(); var FoldersToExplore = new LinkedList <String>(); // Folders to Explore. foreach (var PairSourceFile in SourceFiles) { CheckCanceling(); var SourceFile = PairSourceFile.Value; var SourceFileName = PairSourceFile.Key; if (SourceFile.Type == FileSystemEntry.EntryType.Directory) { FoldersToExplore.AddLast(FileSystem.CombinePath(Path, SourceFileName)); } } foreach (var PairSourceFile in SourceFiles) { CheckCanceling(); var SourceFile = PairSourceFile.Value; var SourceFileName = PairSourceFile.Key; // New file (No contained in the Destination). if (!DestinationFiles.ContainsKey(SourceFileName)) { // Add New Files. if (_SynchronizationMode.HasFlag(SynchronizationMode.CopyNewFiles)) { FilesToUpdate.AddLast(SourceFile); } } // Existant file (Contained in the Destination) else { FileSystemEntry DestinationFile = DestinationFiles[SourceFileName]; bool AreEquals = !SourceFile.SpecialFlags.HasFlag(FileSystemEntry.SpecialFlagsTypes.SynchronizeAlways); // Check old files for updated. if (_SynchronizationMode.HasFlag(SynchronizationMode.UpdateOldFiles)) { if (_ReferenceMode.HasFlag(ReferenceMode.Size) && (SourceFile.Size != DestinationFile.Size)) { AreEquals = false; } if (_ReferenceMode.HasFlag(ReferenceMode.LastWriteTime) && (SourceFile.Time.LastWriteTime != DestinationFile.Time.LastWriteTime)) { //Console.WriteLine(SourceFile + ": " + SourceFile.Time.LastWriteTime + " != " + DestinationFile.Time.LastWriteTime); AreEquals = false; } } if (!AreEquals) { FilesToUpdate.AddLast(SourceFile); } } } // Delete Old Files. if (_SynchronizationMode.HasFlag(SynchronizationMode.DeleteOldFiles)) { throw (new NotImplementedException()); /* * foreach (var PairDestinationFile in DestinationFiles) * { * CheckCanceling(); * * var DestinationFile = PairDestinationFile.Value; * var DestinationFileName = PairDestinationFile.Key; * * // File was deleted (No contained in the Source). * if (!SourceFiles.ContainsKey(DestinationFileName)) * { * FilesToRemove.AddLast(DestinationFile); * } * } */ } int step = 0; int steps = FilesToUpdate.Count + FilesToRemove.Count + FoldersToExplore.Count; foreach (var FileToUpdate in FilesToUpdate) { String FileToUpdatePathFileName = FileSystem.CombinePath(Path, FileToUpdate.Name); CheckCanceling(); CallStep(GetStep(StepFrom, StepTo, step++, steps), String.Format(UpdatingFormat, FileToUpdatePathFileName)); if (FileToUpdate.Type == FileSystemEntry.EntryType.Directory) { Console.WriteLine("Directory: " + FileToUpdatePathFileName); CreateFolder(FileToUpdatePathFileName); } else { CopyFile(FileToUpdatePathFileName); } } foreach (var FileToRemove in FilesToRemove) { String FileToRemovePathFileName = FileSystem.CombinePath(Path, FileToRemove.Name); CheckCanceling(); CallStep(GetStep(StepFrom, StepTo, step++, steps), String.Format(RemovingFormat, FileToRemovePathFileName)); RemoveFile(FileToRemovePathFileName); } foreach (var FolderName in FoldersToExplore) { CheckCanceling(); _SynchronizeFolder( FolderName, GetStep(StepFrom, StepTo, step + 0, steps), GetStep(StepFrom, StepTo, step + 1, steps) ); step++; } }