private IEnumerable<FileInfo> InternalSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, SftpSynchronizeDirectoriesAsyncResult asynchResult)
{
if (!Directory.Exists(sourcePath))
throw new FileNotFoundException(string.Format("Source directory not found: {0}", sourcePath));
var uploadedFiles = new List<FileInfo>();
var sourceDirectory = new DirectoryInfo(sourcePath);
var sourceFiles = FileSystemAbstraction.EnumerateFiles(sourceDirectory, searchPattern).ToList();
if (sourceFiles.Count == 0)
return uploadedFiles;
#region Existing Files at The Destination
var destFiles = InternalListDirectory(destinationPath, null);
var destDict = new Dictionary<string, SftpFile>();
foreach (var destFile in destFiles)
{
if (destFile.IsDirectory)
continue;
destDict.Add(destFile.Name, destFile);
}
#endregion
#region Upload the difference
const Flags uploadFlag = Flags.Write | Flags.Truncate | Flags.CreateNewOrOpen;
foreach (var localFile in sourceFiles)
{
var isDifferent = !destDict.ContainsKey(localFile.Name);
if (!isDifferent)
{
var temp = destDict[localFile.Name];
// TODO: Use md5 to detect a difference
//ltang: File exists at the destination => Using filesize to detect the difference
isDifferent = localFile.Length != temp.Length;
}
if (isDifferent)
{
var remoteFileName = string.Format(CultureInfo.InvariantCulture, @"{0}/{1}", destinationPath, localFile.Name);
try
{
using (var file = File.OpenRead(localFile.FullName))
{
InternalUploadFile(file, remoteFileName, uploadFlag, null, null);
}
uploadedFiles.Add(localFile);
if (asynchResult != null)
{
asynchResult.Update(uploadedFiles.Count);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Failed to upload {0} to {1}", localFile.FullName, remoteFileName), ex);
}
}
}
#endregion
return uploadedFiles;
}