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++;
}
}