public static SyncAction chkDirUpdate(FileUnit sDir, FileUnit tDir, bool isSDirty, bool isTDirty) { if (sDir != null && tDir == null) return SyncAction.CreateTargetDir; else return SyncAction.CreateSourceDir; }
public static String ComputeMyHash(FileUnit myFile) { FileStream myFileStream = new FileStream(myFile.AbsolutePath, FileMode.Open, FileAccess.Read); String strHash = ""; if (myFile.Size < 30000) { byte[] tmpHash = new SHA1Managed().ComputeHash(myFileStream); strHash = BitConverter.ToString(tmpHash, 0).Replace("-", ""); } else { byte[] fileHeader = new byte[30000]; myFileStream.Read(fileHeader, 0, 30000); byte[] tmpHash = new SHA1Managed().ComputeHash(fileHeader); strHash = BitConverter.ToString(tmpHash, 0).Replace("-", ""); } myFileStream.Dispose(); return strHash; }
public void AddDataRow(FileUnit u, SyncAction action) { string path = ""; AddImageToList(u); DataRow row = dtCompare.NewRow(); if (u.AbsolutePath.StartsWith(source)) { path = u.AbsolutePath.Substring(source.Length); if (!u.IsDirectory) { row[1] = u.Size; row[2] = u.LastWriteTime; } } else { path = u.AbsolutePath.Substring(target.Length); if (!u.IsDirectory) { row[5] = u.Size; row[6] = u.LastWriteTime; } } if (u.Match != null) { row[5] = u.Match.Size; row[6] = u.Match.LastWriteTime; } row[0] = path; row[3] = action; row[4] = path; row[7] = u.Extension; row[8] = u; dtCompare.Rows.Add(row); }
public void AddDataRow(FileUnit u, SyncAction action) { AddImageToList(u); DataRow row = _dtCompare.NewRow(); if (u.AbsolutePath.StartsWith(_source)) { row[0] = u.AbsolutePath.Substring(_source.Length); row[4] = u.MatchingPath; if (!u.IsDirectory) { row[1] = u.Size; row[2] = u.LastWriteTime; } if (u.Match != null) { row[5] = u.Match.Size; row[6] = u.Match.LastWriteTime; } } else { row[4] = u.AbsolutePath.Substring(_target.Length); row[0] = u.MatchingPath; if (!u.IsDirectory) { row[5] = u.Size; row[6] = u.LastWriteTime; } } row[3] = row[9] = action; row[7] = u.Extension; row[8] = u; row[10] = (u.IsDirectory) ? "dir" : "file"; _dtCompare.Rows.Add(row); }
public static SyncAction chkFileUpdate(FileUnit sFile, FileUnit tFile, bool isSDirty, bool isTDirty) { if (isSDirty == true && isTDirty == false) return SyncAction.CopyFileToTarget; else if (isSDirty == false && isTDirty == true) return SyncAction.CopyFileToSource; else { if (sFile != null && tFile != null) { if (sFile.LastWriteTime > tFile.LastWriteTime) return SyncAction.CopyFileToTarget; else return SyncAction.CopyFileToSource; } else { if (sFile == null && tFile != null) return SyncAction.CopyFileToSource; else return SyncAction.CopyFileToTarget; } } }
static SyncAction fileRename(FileUnit sFile, FileUnit tFile) { if (sFile.LastWriteTime < tFile.LastWriteTime) return SyncAction.RenameSourceFile; else return SyncAction.RenameTargetFile; }
static SyncAction chkFileDelete(FileUnit sFile, FileUnit tFile) { if (sFile == null) return SyncAction.DeleteTargetFile; else return SyncAction.DeleteSourceFile; }
static void deleteEmptyFolders(FileUnit u) { string sDir = (u.IsDirectory) ? u.AbsolutePath : Directory.GetParent(u.AbsolutePath).FullName; string tDir = (u.IsDirectory) ? u.MatchingPath : Directory.GetParent(u.MatchingPath).FullName; try { Directory.Delete(sDir); Directory.Delete(tDir); } catch { } }
/// <summary> /// Performs comparison of Files between current state and meta data state /// </summary> /// <param name="u"></param> /// <param name="relativePath"></param> private void CompareTgtFiles(FileUnit u, String relativePath) { if (MetaDataExists()) { if (_tMetaData.Primary.ContainsKey(relativePath)) { if ((u.LastWriteTime - _tMetaData.GetByPrimary(relativePath).LastWriteTime).Duration().TotalSeconds <= _task.Settings.IgnoreTimeChange || Utility.ComputeMyHash(u).Equals(_tMetaData.GetByPrimary(relativePath).Hash)) { u.Hash = _tMetaData.PriSub[relativePath]; _tCleanFiles.Add(relativePath, u.Hash, u); _tMetaData.RemoveByPrimary(relativePath); } else { if (File.Exists(_task.Source + relativePath)) { _tgtDirtySize += (u.Size) - (new FileInfo(_task.Source + relativePath)).Length; } else _tgtDirtySize += u.Size; u.Hash = "M-" + _tMetaData.PriSub[relativePath]; _tDirtyFiles.Add(relativePath, u.Hash, u); _tMetaData.RemoveByPrimary(relativePath); } } else { if (File.Exists(_task.Source + relativePath)) { _tgtDirtySize += (u.Size) - (new FileInfo(_task.Source + relativePath)).Length; } else _tgtDirtySize += u.Size; u.Hash = "C-" + Utility.ComputeMyHash(u); _tDirtyFiles.Add(relativePath, u.Hash, u); } } else { if (File.Exists(_task.Source + relativePath)) { _tgtDirtySize += (u.Size) - (new FileInfo(_task.Source + relativePath)).Length; } else _tgtDirtySize += u.Size; u.Hash = "C-";// +Utility.ComputeMyHash(u); _tDirtyFiles.Add(relativePath, u.Hash, u); } }
/// <summary> /// Removes files/folders, based on the Filters set up by this SyncTask /// </summary> /// <param name="sRevPathLen"></param> /// <param name="tRevPathLen"></param> private void RemoveExclusions(int sRevPathLen, int tRevPathLen) { List<FileUnit> tempSrcFiles = new List<FileUnit>(); List<FileUnit> tempDestFiles = new List<FileUnit>(); #region removeSrcExclusions foreach (FileUnit u in _srcFiles) { String folderRelativePath = u.AbsolutePath.Substring(sRevPathLen); if (u.IsDirectory) { if (!_task.Filters.IsSourceDirExcluded(u.AbsolutePath)) tempSrcFiles.Add(u); else { if (_sMetaData != null && _sMetaData.ContainsPriKey(folderRelativePath)) _sMetaData.RemoveByPrimary(folderRelativePath); if (_sMetaData != null) { u.Hash = folderRelativePath; _sCleanDirs.Add(folderRelativePath, u.Hash, u); } } } else { String relativePath = u.AbsolutePath.Substring(sRevPathLen); bool targetExcluded = false; if (File.Exists(_task.Target + relativePath)) targetExcluded = _task.Filters.IsFileExcluded(new FileInfo(_task.Target + relativePath)); if (!_task.Filters.IsFileExcluded(new FileInfo(u.AbsolutePath)) && !_task.Filters.IsSourceDirExcluded(u.AbsolutePath) && !targetExcluded) { tempSrcFiles.Add(u); } else { if (_sMetaData != null && _sMetaData.ContainsPriKey(relativePath)) _sMetaData.RemoveByPrimary(relativePath); if (_tMetaData != null && _tMetaData.ContainsPriKey(relativePath)) _tMetaData.RemoveByPrimary(relativePath); _fileExclusions.Add(relativePath); if (_sMetaData != null) { u.Hash = Utility.ComputeMyHash(u); _sCleanFiles.Add(relativePath, u.Hash, u); } if (File.Exists(_task.Target + relativePath)) { FileUnit targetUnit = new FileUnit(_task.Target + relativePath); if (_tMetaData != null) { targetUnit.Hash = Utility.ComputeMyHash(targetUnit); _tCleanFiles.Add(relativePath, targetUnit.Hash, targetUnit); } } } } } #endregion #region removeTgtExclusions foreach (FileUnit u in _tgtFiles) { String folderRelativePath = u.AbsolutePath.Substring(tRevPathLen); if (u.IsDirectory) { if (!_task.Filters.IsTargetDirExcluded(u.AbsolutePath)) tempDestFiles.Add(u); else { if (_tMetaData != null && _tMetaData.ContainsPriKey(folderRelativePath)) _tMetaData.RemoveByPrimary(folderRelativePath); if (_tMetaData != null) { u.Hash = folderRelativePath; _tCleanDirs.Add(folderRelativePath, u.Hash, u); } } } else { String relativePath = u.AbsolutePath.Substring(tRevPathLen); if (!_fileExclusions.Contains(relativePath) && !_task.Filters.IsFileExcluded(new FileInfo(u.AbsolutePath)) && !_task.Filters.IsTargetDirExcluded(u.AbsolutePath)) { tempDestFiles.Add(u); } else { if (_sMetaData != null && _sMetaData.ContainsPriKey(relativePath)) _sMetaData.RemoveByPrimary(relativePath); if (_tMetaData != null && _tMetaData.ContainsPriKey(relativePath)) _tMetaData.RemoveByPrimary(relativePath); _fileExclusions.Add(relativePath); if (!_tCleanFiles.ContainsPriKey(relativePath)) { if (_tMetaData != null) { u.Hash = Utility.ComputeMyHash(u); _tCleanFiles.Add(relativePath, u.Hash, u); } } } } } #endregion _srcFiles = tempSrcFiles; _tgtFiles = tempDestFiles; }
private void ComputeStatisticsResult(FileUnit u, SyncAction action) { switch (action) { case SyncAction.CopyFileToSource: _numOfTFilesCpy++; if (u.Match != null) { _tFilesCpySize += u.Match.Size; _numOfSFilesOW++; _sFilesOWSize += u.Size; } else _tFilesCpySize += u.Size; break; case SyncAction.CopyFileToTarget: _numOfSFilesCpy++; _sFilesCpySize += u.Size; if (u.Match != null) { _numOfTFilesOW++; _tFilesOWSize += u.Match.Size; } break; case SyncAction.DeleteSourceFile: _numOfSFilesDel++; _sFilesDelSize += u.Size; break; case SyncAction.DeleteTargetFile: _numOfTFilesDel++; _tFilesDelSize += u.Size; break; case SyncAction.KeepBothCopies: _numOfSFilesCpy++; _numOfTFilesCpy++; _sFilesCpySize += u.Size; _tFilesCpySize += u.Match.Size; break; case SyncAction.CreateSourceDir: _numOfSFoldersC++; break; case SyncAction.CreateTargetDir: _numOfTFoldersC++; break; case SyncAction.DeleteBothDir: _numOfSFoldersDel++; _numOfTFoldersDel++; break; case SyncAction.DeleteSourceDir: _numOfSFoldersDel++; break; case SyncAction.DeleteTargetDir: _numOfTFoldersDel++; break; } }
private void CheckTargetFileConflict(FileUnit u, FileUnit sLastSync, FileUnit tLastSync) { if (tLastSync != null && sLastSync != null) { // source deleted only if (tLastSync.LastWriteTime == u.LastWriteTime) { this.deleteTargetFilesList.Add(u); } //source deleted, target changed else if (tLastSync.LastWriteTime != u.LastWriteTime) { this.conflictFilesList.Add(u); } } else this.newTargetFilesList.Add(u); }
private void AddImageToList(FileUnit u) { if (!imageList.Images.ContainsKey(u.Extension)) imageList.Images.Add(u.Extension, ShellIcon.GetSmallIcon(u.AbsolutePath).ToBitmap()); }
private void ReadFromPreviewList(CustomDictionary<string, string, PreviewUnit> previewList) { foreach (var item in previewList.PriSub) { string srcRelativePath = item.Key; string tgtRelativePath = item.Value; PreviewUnit unit = previewList.GetByPrimary(srcRelativePath); if (unit.sAction != SyncAction.NoAction) { FileUnit u = null; if (!unit.srcFlag.Equals("D")) { u = new FileUnit(_source + srcRelativePath); u.MatchingPath = tgtRelativePath; if (!unit.tgtFlag.Equals("D")) u.Match = new FileUnit(_target + tgtRelativePath); } else { if (!unit.tgtFlag.Equals("D")) { u = new FileUnit(_target + tgtRelativePath); u.MatchingPath = srcRelativePath; } } if (u == null) continue; ComputeStatisticsResult(u, unit.sAction); AddDataRow(u, unit.sAction); } } }
/// <summary> /// Perform sync action based on preview result between source dirty file and target clean file. dirty = modification, deletion and rename. /// </summary> /// <param name="srcRelativePath"></param> /// <param name="tgtRelativePath"></param> /// <param name="preview"></param> private void SyncPreviewSrcDirtyTgtClean(String srcRelativePath, String tgtRelativePath, PreviewUnit preview) { switch (preview.sAction) { case SyncAction.CopyFileToTarget: { CheckAndCreateFolder(_tgtPath + srcRelativePath); File.Copy(_srcPath + srcRelativePath, _tgtPath + srcRelativePath, true); long fileSize = new FileInfo(_srcPath + srcRelativePath).Length; Logger.WriteLog(Logger.LogType.CopySRC, _srcPath + srcRelativePath, fileSize, _tgtPath + srcRelativePath, fileSize); FileUnit myFile = new FileUnit(_srcPath + srcRelativePath); myFile.Hash = Utility.ComputeMyHash(myFile); _updatedList.Add(srcRelativePath, myFile.Hash, myFile); } break; case SyncAction.RenameTargetFile: { CheckAndCreateFolder(_tgtPath + srcRelativePath); File.Move(_tgtPath + preview.cleanRelativePath, _tgtPath + srcRelativePath); long fileSize = new FileInfo(_tgtPath + srcRelativePath).Length; Logger.WriteLog(Logger.LogType.RenameTGT, _tgtPath + preview.cleanRelativePath, fileSize, _tgtPath + srcRelativePath, fileSize); FileUnit myFile = new FileUnit(_tgtPath + srcRelativePath); myFile.Hash = Utility.ComputeMyHash(myFile); _updatedList.Add(srcRelativePath, myFile.Hash, myFile); } break; case SyncAction.DeleteTargetFile: { long fileSize = new FileInfo(_tgtPath + srcRelativePath).Length; File.Delete(_tgtPath + srcRelativePath); Logger.WriteLog(Logger.LogType.DeleteTGT, null, 0, _tgtPath + srcRelativePath, fileSize); } break; case SyncAction.NoAction: { _updatedList.Add(preview.cleanRelativePath, preview.cleanFileUnit.Hash, preview.cleanFileUnit); } break; } }
/// <summary> /// Perform sync between source dirty file and target clean file. dirty = modification, deletion and rename. /// </summary> /// <param name="relativePath"></param> /// <param name="srcFlag"></param> private void SyncSrcDirtyTgtClean(String relativePath, String srcFlag) { switch (srcFlag) { case cFlag: { if (!_srcRenameList.ContainsPriKey(relativePath)) { FileUnit fileMeta = new FileUnit(_srcPath + relativePath); String hashCode = Utility.ComputeMyHash(fileMeta); fileMeta.Hash = hashCode; CheckAndCreateFolder(_tgtPath + relativePath); File.Copy(_srcPath + relativePath, _tgtPath + relativePath); _updatedList.Add(relativePath, hashCode, fileMeta); _summary.iSrcFileCopy++; long fileSize = new FileInfo(_srcPath + relativePath).Length; Logger.WriteLog(Logger.LogType.CopySRC, _srcPath + relativePath, fileSize, _tgtPath + relativePath, fileSize); } else { String delRelativePath = _srcRenameList.PriSub[relativePath]; FileUnit fileMeta = _srcDirtyFilesList.GetByPrimary(relativePath); _updatedList.Add(relativePath, fileMeta.Hash.Substring(2), fileMeta); CheckAndCreateFolder(_tgtPath + relativePath); File.Move(_tgtPath + delRelativePath, _tgtPath + relativePath); _tgtCleanFilesList.RemoveByPrimary(delRelativePath); _summary.iTgtFileRename++; long fileSize = new FileInfo(_tgtPath + relativePath).Length; Logger.WriteLog(Logger.LogType.RenameTGT, _tgtPath + delRelativePath, fileSize, _tgtPath + relativePath, fileSize); } } break; case mFlag: { FileUnit fileMeta = new FileUnit(_srcPath + relativePath); String hashCode = Utility.ComputeMyHash(fileMeta); fileMeta.Hash = hashCode; CheckAndCreateFolder(_tgtPath + relativePath); File.Copy(_srcPath + relativePath, _tgtPath + relativePath, true); _updatedList.Add(relativePath, hashCode, fileMeta); _tgtCleanFilesList.RemoveByPrimary(relativePath); _summary.iSrcFileCopy++; _summary.iTgtFileOverwrite++; long fileSize = new FileInfo(_srcPath + relativePath).Length; Logger.WriteLog(Logger.LogType.CopySRC, _srcPath + relativePath, fileSize, _tgtPath + relativePath, fileSize); } break; case dFlag: { long fileSize = new FileInfo(_tgtPath + relativePath).Length; File.Delete(_tgtPath + relativePath); _tgtCleanFilesList.RemoveByPrimary(relativePath); _summary.iTgtFileDelete++; Logger.WriteLog(Logger.LogType.DeleteTGT, null, 0, _tgtPath + relativePath, fileSize); } break; } }
/// <summary> /// Perform preview sync between source dirty file and target dirty file. dirty = modification, deletion and rename. /// </summary> /// <param name="srcRelativePath"></param> /// <param name="srcFlag"></param> /// <param name="srcFile"></param> /// <param name="tgtRelativePath"></param> /// <param name="tgtFlag"></param> /// <param name="tgtFile"></param> private void PreviewSrcDirtyTgtDirty(String srcRelativePath, String srcFlag, FileUnit srcFile, String tgtRelativePath, String tgtFlag, FileUnit tgtFile) { PreviewUnit preview = new PreviewUnit(); preview.intDirtyType = 2; if (_tgtDirtyFilesList.ContainsPriKey(tgtRelativePath)) { if (_tgtRenameList.ContainsSecKey(tgtRelativePath) && !_tgtRenameList.ContainsPriKey(srcRelativePath)) { preview.cleanRelativePath = tgtRelativePath; preview.cleanFileUnit = _tgtDirtyFilesList.GetByPrimary(tgtRelativePath); tgtFlag = cFlag; List<String> lstFiles = _tgtRenameList.SubPri[tgtRelativePath]; tgtRelativePath = lstFiles[0]; tgtFile = _tgtRenameList.GetByPrimary(tgtRelativePath); } else if (!_tgtDirtyFilesList.ContainsPriKey(srcRelativePath)) { tgtFlag = "" + _tgtDirtyFilesList.PriSub[tgtRelativePath][0]; preview.cleanRelativePath = tgtRelativePath; preview.cleanFileUnit = tgtFile = _tgtDirtyFilesList.GetByPrimary(tgtRelativePath); } else if (srcFlag.Equals(cFlag) && _srcRenameList.ContainsPriKey(srcRelativePath)) { String cleanPath = _srcRenameList.PriSub[srcRelativePath]; preview.cleanRelativePath = cleanPath; preview.cleanFileUnit = _srcDirtyFilesList.GetByPrimary(cleanPath); } else { preview.cleanRelativePath = srcRelativePath; preview.cleanFileUnit = srcFile; } } int iSrcSlash = srcRelativePath.LastIndexOf('\\'); int iTgtSlash = tgtRelativePath.LastIndexOf('\\'); String srcFilePath = ""; if (iSrcSlash > 0) { srcFilePath = srcRelativePath.Substring(0, iSrcSlash + 1); } String tgtFilePath = ""; if (iTgtSlash > 0) { tgtFilePath = tgtRelativePath.Substring(0, iTgtSlash + 1); } preview.srcFlag = srcFlag; preview.tgtFlag = tgtFlag; preview.srcFile = srcFile; preview.tgtFile = tgtFile; preview.sAction = SyncAction.NoAction; if (!srcFilePath.Equals(tgtFilePath)) { preview.isPathDiff = true; if (_taskSettings.FolderConflict == TaskSettings.ConflictFolderAction.KeepSourceName) { if (!tgtFlag.Equals(dFlag)) { if (srcFlag.Equals(dFlag) && _srcDirtyFoldersList.ContainsSecKey(dFlag + "-" + srcFilePath)) { PreviewCheckAndCreateTgtFolder(tgtRelativePath); preview.sAction = checkConflicts(srcFile, tgtFile, srcFlag, tgtFlag); } else { if (_srcDirtyFoldersList.ContainsPriKey(tgtFilePath)) _srcDirtyFoldersList.RemoveByPrimary(tgtFilePath); if (_tgtDirtyFoldersList.ContainsPriKey(tgtFilePath)) { PreviewUnit previewFolder = new PreviewUnit(); previewFolder.sAction = SyncAction.DeleteTargetDir; previewFolder.srcFlag = dFlag; previewFolder.tgtFlag = cFlag; _previewFoldersList.Add(tgtFilePath, tgtFilePath, previewFolder); _tgtDirtyFoldersList.RemoveByPrimary(tgtFilePath); } } if (preview.sAction == SyncAction.NoAction) preview.sAction = SyncAction.RenameTargetFile; } else preview.sAction = SyncAction.CopyFileToTarget; } else { if (!srcFlag.Equals(dFlag)) { if (tgtFlag.Equals(dFlag) && _tgtDirtyFoldersList.ContainsSecKey(dFlag + "-" + tgtFilePath)) { PreviewCheckAndCreateSrcFolder(srcRelativePath); preview.sAction = checkConflicts(srcFile, tgtFile, srcFlag, tgtFlag); } else { if (_srcDirtyFoldersList.ContainsPriKey(srcFilePath)) _srcDirtyFoldersList.RemoveByPrimary(srcFilePath); if (_tgtDirtyFoldersList.ContainsPriKey(srcFilePath)) { PreviewUnit previewFolder = new PreviewUnit(); previewFolder.sAction = SyncAction.DeleteSourceDir; previewFolder.srcFlag = cFlag; previewFolder.tgtFlag = dFlag; _previewFoldersList.Add(srcFilePath, srcFilePath, previewFolder); _tgtDirtyFoldersList.RemoveByPrimary(srcFilePath); } } if (preview.sAction == SyncAction.NoAction) preview.sAction = SyncAction.RenameSourceFile; } else preview.sAction = SyncAction.CopyFileToSource; } } else { preview.isPathDiff = false; if (srcFlag.Equals(cFlag) && _srcRenameList.ContainsPriKey(srcRelativePath)) { String delSrcFile = _srcRenameList.PriSub[srcRelativePath]; preview.srcOldRelativePath = delSrcFile; if (_tgtCleanFilesList.ContainsPriKey(delSrcFile)) _tgtCleanFilesList.RemoveByPrimary(delSrcFile); if (tgtFlag.Equals(cFlag) && _tgtRenameList.ContainsPriKey(srcRelativePath)) { String delTgtFile = _tgtRenameList.PriSub[srcRelativePath]; preview.tgtOldRelativePath = delTgtFile; if (_srcCleanFilesList.ContainsPriKey(delTgtFile)) _srcCleanFilesList.RemoveByPrimary(delTgtFile); } } else if (srcFlag.Equals(cFlag) && _tgtRenameList.ContainsPriKey(srcRelativePath)) { String delTgtFile = _tgtRenameList.PriSub[srcRelativePath]; preview.tgtOldRelativePath = delTgtFile; if (_srcCleanFilesList.ContainsPriKey(delTgtFile)) _srcCleanFilesList.RemoveByPrimary(delTgtFile); } preview.sAction = checkConflicts(srcFile, tgtFile, srcFlag, tgtFlag); } _tgtDirtyFilesList.RemoveByPrimary(tgtRelativePath); _previewFilesList.Add(srcRelativePath, tgtRelativePath, preview); }
private void ProcessTargetFileUnit(FileUnit t, string sDirPath, string tDirPath, Stack<SyncTask> stack) { t.MatchingPath = sDirPath + "\\" + t.Name; FileUnit sLastSync = null, tLastSync = null; if (sMetaData != null && tMetaData != null) { try { tLastSync = tMetaData[t.AbsolutePath]; sLastSync = sMetaData[t.MatchingPath]; } catch { } } CheckTargetFileConflict(t, sLastSync, tLastSync); if (t.IsDirectory) stack.Push(new SyncTask(t.MatchingPath, t.AbsolutePath)); }
private void ProcessSourceFileUnit(FileUnit s, string sDirPath, string tDirPath, Stack<SyncTask> stack) { s.MatchingPath = tDirPath + "\\" + s.Name; FileUnit sLastSync = null, tLastSync = null; if (sMetaData != null && tMetaData != null) { try { sLastSync = sMetaData[s.AbsolutePath]; tLastSync = tMetaData[s.MatchingPath]; } catch { } } if (s.Match == null) CheckSourceFileConflict(s, sLastSync, tLastSync); else { s.Match.MatchingPath = sDirPath + "\\" + s.Name; CheckMatchFilesConflict(s, sLastSync, tLastSync); } if (s.IsDirectory) stack.Push(new SyncTask(s.AbsolutePath, s.MatchingPath)); }
static void updateDir(FileUnit sDir, FileUnit tDir, bool isSDirty, bool isTDirty, Dictionary<string, FileUnit> sMeta, Dictionary<string, FileUnit> tMeta) { switch (chkDirUpdate(sDir, tDir, isSDirty, isTDirty)) { case SyncAction.CreateSourceDir: Directory.CreateDirectory(tDir.MatchingPath); tMeta.Add(tDir.AbsolutePath, tDir); FileUnit newSource = new FileUnit(tDir.MatchingPath); sMeta.Add(newSource.AbsolutePath, newSource); break; case SyncAction.CreateTargetDir: Directory.CreateDirectory(sDir.MatchingPath); sMeta.Add(sDir.AbsolutePath, sDir); FileUnit newTarget = new FileUnit(sDir.MatchingPath); tMeta.Add(newTarget.AbsolutePath, newTarget); break; } }
/// <summary> /// Perform file operation for conflicting files. /// </summary> /// <param name="srcFile"></param> /// <param name="tgtFile"></param> /// <param name="srcFlag"></param> /// <param name="tgtFlag"></param> /// <param name="srcPath"></param> /// <param name="tgtPath"></param> private void executeSyncAction(FileUnit srcFile, FileUnit tgtFile, String srcFlag, String tgtFlag, String srcPath, String tgtPath) { switch (checkConflicts(srcFile, tgtFile, srcFlag, tgtFlag)) { case SyncAction.KeepBothCopies: { String srcFileName = srcFile.Name; String tgtFileName = tgtFile.Name; if (srcFile.Name.Equals(tgtFile.Name)) { do { int iExt = srcFileName.LastIndexOf('.'); // Locate the index position of the file extension if (iExt > 0) // File with file extension { srcFileName = srcFileName.Substring(0, iExt) + "(1)" + srcFileName.Substring(iExt); tgtFileName = tgtFileName.Substring(0, iExt) + "(2)" + tgtFileName.Substring(iExt); } else if (iExt == -1) // File without file extension { srcFileName = srcFileName + "(1)"; tgtFileName = tgtFileName + "(2)"; } } while (File.Exists(srcPath + srcFileName) || File.Exists(srcPath + tgtFileName) || File.Exists(tgtPath + srcFileName) || File.Exists(tgtPath + tgtFileName)); File.Move(srcPath + srcFile.Name, srcPath + srcFileName); File.Move(tgtPath + tgtFile.Name, tgtPath + tgtFileName); } CheckAndCreateFolder(tgtPath + srcFileName); CheckAndCreateFolder(srcPath + tgtFileName); File.Copy(srcPath + srcFileName, tgtPath + srcFileName); File.Copy(tgtPath + tgtFileName, srcPath + tgtFileName); FileUnit srcFileMeta = new FileUnit(srcPath + srcFileName); String srcHashcode = Utility.ComputeMyHash(srcFileMeta); srcFileMeta.Hash = srcHashcode; FileUnit tgtFileMeta = new FileUnit(tgtPath + tgtFileName); String tgtHashcode = Utility.ComputeMyHash(tgtFileMeta); tgtFileMeta.Hash = tgtHashcode; _updatedList.Add(srcPath.Substring(_srcPath.Length) + srcFileName, srcHashcode, srcFileMeta); _updatedList.Add(tgtPath.Substring(_tgtPath.Length) + tgtFileName, tgtHashcode, tgtFileMeta); _summary.iSrcFileCopy++; _summary.iTgtFileCopy++; long fileSize = new FileInfo(srcPath + srcFileName).Length; Logger.WriteLog(Logger.LogType.CopySRC, srcPath + srcFileName, fileSize, tgtPath + srcFileName, fileSize); fileSize = new FileInfo(tgtPath + tgtFileName).Length; Logger.WriteLog(Logger.LogType.CopyTGT, tgtPath + tgtFileName, fileSize, srcPath + tgtFileName, fileSize); } break; case SyncAction.CopyFileToTarget: { FileUnit fileMeta = new FileUnit(srcPath + srcFile.Name); String strHashcode = Utility.ComputeMyHash(fileMeta); fileMeta.Hash = strHashcode; CheckAndCreateFolder(tgtPath + srcFile.Name); File.Copy(srcPath + srcFile.Name, tgtPath + srcFile.Name, true); _updatedList.Add(srcPath.Substring(_srcPath.Length) + srcFile.Name, strHashcode, fileMeta); _summary.iSrcFileCopy++; long fileSize = new FileInfo(srcPath + srcFile.Name).Length; Logger.WriteLog(Logger.LogType.CopySRC, srcPath + srcFile.Name, fileSize, tgtPath + srcFile.Name, fileSize); } break; case SyncAction.CopyFileToSource: { FileUnit fileMeta = new FileUnit(tgtPath + tgtFile.Name); String strHashcode = Utility.ComputeMyHash(fileMeta); fileMeta.Hash = strHashcode; CheckAndCreateFolder(srcPath + tgtFile.Name); File.Copy(tgtPath + tgtFile.Name, srcPath + tgtFile.Name, true); _updatedList.Add(tgtPath.Substring(_tgtPath.Length) + tgtFile.Name, strHashcode, fileMeta); _summary.iTgtFileCopy++; long fileSize = new FileInfo(tgtPath + tgtFile.Name).Length; Logger.WriteLog(Logger.LogType.CopyTGT, tgtPath + tgtFile.Name, fileSize, srcPath + tgtFile.Name, fileSize); } break; case SyncAction.DeleteSourceFile: { long fileSize = new FileInfo(srcPath + srcFile.Name).Length; File.Delete(srcPath + srcFile.Name); _summary.iSrcFileDelete++; Logger.WriteLog(Logger.LogType.DeleteSRC, srcPath + srcFile.Name, fileSize, null, 0); } break; case SyncAction.DeleteTargetFile: { long fileSize = new FileInfo(tgtPath + tgtFile.Name).Length; File.Delete(tgtPath + tgtFile.Name); _summary.iTgtFileDelete++; Logger.WriteLog(Logger.LogType.DeleteTGT, null, 0, tgtPath + tgtFile.Name, fileSize); } break; case SyncAction.NoAction: { if (srcFlag.Equals(cFlag) && tgtFlag.Equals(cFlag)) { String relPath = (srcPath + srcFile.Name).Substring(_srcPath.Length); if (!_updatedList.ContainsPriKey(relPath)) { FileUnit fileMeta = new FileUnit(_srcPath + relPath); String hashCode = Utility.ComputeMyHash(fileMeta); fileMeta.Hash = hashCode; _updatedList.Add(relPath, hashCode, fileMeta); } } } break; } }
static void updateFile(FileUnit sFile, FileUnit tFile, bool isSDirty, bool isTDirty, Dictionary<string, FileUnit> sMeta, Dictionary<string, FileUnit> tMeta) { switch (chkFileUpdate(sFile, tFile, isSDirty, isTDirty)) { case SyncAction.CopyFileToSource: string parent = Directory.GetParent(tFile.MatchingPath).FullName; if (!Directory.Exists(parent)) Directory.CreateDirectory(parent); File.Copy(tFile.AbsolutePath, tFile.MatchingPath, true); tMeta.Add(tFile.AbsolutePath, tFile); FileUnit newSource = new FileUnit(tFile.MatchingPath); sMeta.Add(newSource.AbsolutePath, newSource); break; case SyncAction.CopyFileToTarget: parent = Directory.GetParent(sFile.MatchingPath).FullName; if (!Directory.Exists(parent)) Directory.CreateDirectory(parent); File.Copy(sFile.AbsolutePath, sFile.MatchingPath, true); sMeta.Add(sFile.AbsolutePath, sFile); FileUnit newTarget = new FileUnit(sFile.MatchingPath); tMeta.Add(newTarget.AbsolutePath, newTarget); break; } }
/// <summary> /// Performs comparison of Folders between current state and meta data state /// </summary> /// <param name="u"></param> /// <param name="folderRelativePath"></param> private void CompareTgtDirs(FileUnit u, String folderRelativePath) { if (MetaDataExists()) { if (_tMetaData.Primary.ContainsKey(folderRelativePath)) { u.Hash = folderRelativePath; _tCleanDirs.Add(folderRelativePath, u.Hash, u); _tMetaData.RemoveByPrimary(folderRelativePath); } else { u.Hash = "C-" + folderRelativePath; _tDirtyDirs.Add(folderRelativePath, u.Hash, u); } } else { u.Hash = "C-" + folderRelativePath; _tDirtyDirs.Add(folderRelativePath, u.Hash, u); } }
/// <summary> /// Perform sync between source dirty file and target dirty file. dirty = modification, deletion and rename. /// </summary> /// <param name="srcRelativePath"></param> /// <param name="srcFlag"></param> /// <param name="srcFile"></param> /// <param name="tgtRelativePath"></param> /// <param name="tgtFlag"></param> /// <param name="tgtFile"></param> private void SyncSrcDirtyTgtDirty(String srcRelativePath, String srcFlag, FileUnit srcFile, String tgtRelativePath, String tgtFlag, FileUnit tgtFile) { if (_tgtDirtyFilesList.ContainsPriKey(tgtRelativePath)) { if (_tgtRenameList.ContainsSecKey(tgtRelativePath) && !_tgtRenameList.ContainsPriKey(srcRelativePath)) { tgtFlag = cFlag; List<String> lstFiles = _tgtRenameList.SubPri[tgtRelativePath]; tgtRelativePath = lstFiles[0]; tgtFile = _tgtRenameList.GetByPrimary(tgtRelativePath); } else if (!_tgtDirtyFilesList.ContainsPriKey(srcRelativePath)) { tgtFlag = "" + _tgtDirtyFilesList.PriSub[tgtRelativePath][0]; tgtFile = _tgtDirtyFilesList.GetByPrimary(tgtRelativePath); } } int iSrcSlash = srcRelativePath.LastIndexOf('\\'); int iTgtSlash = tgtRelativePath.LastIndexOf('\\'); String srcFilePath = ""; if (iSrcSlash > 0) { srcFilePath = srcRelativePath.Substring(0, iSrcSlash + 1); } String tgtFilePath = ""; if (iTgtSlash > 0) { tgtFilePath = tgtRelativePath.Substring(0, iTgtSlash + 1); } if (!srcFilePath.Equals(tgtFilePath)) { FileUnit folderMeta; if (_taskSettings.FolderConflict == TaskSettings.ConflictFolderAction.KeepSourceName) { if (!tgtFlag.Equals(dFlag)) { if (srcFlag.Equals(dFlag) && _srcDirtyFoldersList.ContainsSecKey(dFlag + "-" + srcFilePath)) { //File.Move(_tgtPath + tgtRelativePath, _tgtPath + tgtFilePath + tgtRelativePath.Substring(iTgtSlash)); srcFilePath = tgtFilePath; } else { CheckAndCreateFolder(_tgtPath + srcRelativePath); File.Move(_tgtPath + tgtRelativePath, _tgtPath + srcFilePath + tgtRelativePath.Substring(iTgtSlash)); folderMeta = new FileUnit(_tgtPath + srcFilePath); DirectoryInfo dir = new DirectoryInfo(_tgtPath + tgtFilePath); int iFileCount = dir.GetFiles().Length; int iDirCount = dir.GetDirectories().Length; if (iFileCount == 0 && iDirCount == 0) { if (_srcDirtyFoldersList.ContainsPriKey(tgtFilePath)) _srcDirtyFoldersList.RemoveByPrimary(tgtFilePath); if (_tgtDirtyFoldersList.ContainsPriKey(tgtFilePath)) _tgtDirtyFoldersList.RemoveByPrimary(tgtFilePath); _srcDirtyFoldersList.Add(tgtFilePath, dFlag + "-" + tgtFilePath, folderMeta); _tgtDirtyFoldersList.Add(tgtFilePath, dFlag + "-" + tgtFilePath, folderMeta); } } } tgtFilePath = srcFilePath; } else { if (!srcFlag.Equals(dFlag)) { if (tgtFlag.Equals(dFlag) && _tgtDirtyFoldersList.ContainsSecKey(dFlag + "-" + tgtFilePath)) { //File.Move(_srcPath + srcRelativePath, _srcPath + srcFilePath + srcRelativePath.Substring(iSrcSlash)); tgtFilePath = srcFilePath; } else { CheckAndCreateFolder(_srcPath + tgtRelativePath); File.Move(_srcPath + srcRelativePath, _srcPath + tgtFilePath + srcRelativePath.Substring(iSrcSlash)); folderMeta = new FileUnit(_srcPath + tgtFilePath); DirectoryInfo dir = new DirectoryInfo(_srcPath + srcFilePath); int iFileCount = dir.GetFiles().Length; int iDirCount = dir.GetDirectories().Length; if (iFileCount == 0 && iDirCount == 0) { if (_srcDirtyFoldersList.ContainsPriKey(srcFilePath)) _srcDirtyFoldersList.RemoveByPrimary(srcFilePath); if (_tgtDirtyFoldersList.ContainsPriKey(srcFilePath)) _tgtDirtyFoldersList.RemoveByPrimary(srcFilePath); _srcDirtyFoldersList.Add(srcFilePath, dFlag + "-" + srcFilePath, folderMeta); _tgtDirtyFoldersList.Add(srcFilePath, dFlag + "-" + srcFilePath, folderMeta); } } } srcFilePath = tgtFilePath; } executeSyncAction(srcFile, tgtFile, srcFlag, tgtFlag, _srcPath + srcFilePath, _tgtPath + tgtFilePath); _tgtDirtyFilesList.RemoveByPrimary(tgtRelativePath); } else { executeSyncAction(srcFile, tgtFile, srcFlag, tgtFlag, _srcPath + srcFilePath, _tgtPath + srcFilePath); _tgtDirtyFilesList.RemoveByPrimary(tgtRelativePath); if (srcFlag.Equals(cFlag) && _srcRenameList.ContainsPriKey(srcRelativePath)) { String delSrcFile = _srcRenameList.PriSub[srcRelativePath]; if (_tgtCleanFilesList.ContainsPriKey(delSrcFile)) _tgtCleanFilesList.RemoveByPrimary(delSrcFile); if (File.Exists(_tgtPath + delSrcFile)) File.Delete(_tgtPath + delSrcFile); if (tgtFlag.Equals(cFlag) && _tgtRenameList.ContainsPriKey(srcRelativePath)) { String delTgtFile = _tgtRenameList.PriSub[srcRelativePath]; if (_srcCleanFilesList.ContainsPriKey(delTgtFile)) _srcCleanFilesList.RemoveByPrimary(delTgtFile); if (File.Exists(_srcPath + delTgtFile)) File.Delete(_srcPath + delTgtFile); } } else if (srcFlag.Equals(cFlag) && _tgtRenameList.ContainsPriKey(srcRelativePath)) { String delTgtFile = _tgtRenameList.PriSub[srcRelativePath]; if (_srcCleanFilesList.ContainsPriKey(delTgtFile)) _srcCleanFilesList.RemoveByPrimary(delTgtFile); if (File.Exists(_srcPath + delTgtFile)) File.Delete(_srcPath + delTgtFile); } } }
private void CheckMatchFilesConflict(FileUnit u, FileUnit sLastSync, FileUnit tLastSync) { if (sLastSync != null && tLastSync != null) { // source & target files changed if (sLastSync.LastWriteTime != u.LastWriteTime && tLastSync.LastWriteTime != u.Match.LastWriteTime) { this.conflictFilesList.Add(u); } // source change, target unchanged else if (sLastSync.LastWriteTime != u.LastWriteTime && tLastSync.LastWriteTime == u.Match.LastWriteTime) { this.newSourceFilesList.Add(u); } //target changed, source unchanged else if (sLastSync.LastWriteTime == u.LastWriteTime && tLastSync.LastWriteTime != u.Match.LastWriteTime) { this.newTargetFilesList.Add(u.Match); } else this.unchangedFilesList.Add(u); } else { FileComparator comparator = new FileComparator(true, true, true, false); if (!u.IsDirectory && (comparator.Compare(u, u.Match) != 0)) this.conflictFilesList.Add(u); else this.unchangedFilesList.Add(u); } }
/// <summary> /// Select the desired action for conflicting files. /// </summary> /// <param name="sourceDirtyFile"></param> /// <param name="destDirtyFile"></param> /// <param name="s"></param> /// <param name="t"></param> /// <returns></returns> private SyncAction checkConflicts(FileUnit sourceDirtyFile, FileUnit destDirtyFile, String s, String t) { //Compare every single file in dirty source list with dirty destination list to determine what action //to be taken. There are total of four kinds of flags associate with every file in dirty source list. if (s.Equals(mFlag) || s.Equals(rFlag)) { if (t.Equals(mFlag) || t.Equals(cFlag) || t.Equals(rFlag)) { switch (_taskSettings.SrcTgtConflict) { case TaskSettings.ConflictSrcTgtAction.KeepBothCopies: return SyncAction.KeepBothCopies; case TaskSettings.ConflictSrcTgtAction.KeepLatestCopy: if (sourceDirtyFile.LastWriteTime > destDirtyFile.LastWriteTime) //keep the lastest file if two files are both modified { return SyncAction.CopyFileToTarget; } else { return SyncAction.CopyFileToSource; } case TaskSettings.ConflictSrcTgtAction.SourceOverwriteTarget: return SyncAction.CopyFileToTarget; case TaskSettings.ConflictSrcTgtAction.TargetOverwriteSource: return SyncAction.CopyFileToSource; default: return SyncAction.KeepBothCopies; } } else if (t.Equals(dFlag)) //There are two possibilities for a file which was marked as DELETE on destination dirty list. { switch (_taskSettings.SrcConflict) { case TaskSettings.ConflictSrcAction.CopyFileToTarget: return SyncAction.CopyFileToTarget;//copy source to destination case TaskSettings.ConflictSrcAction.DeleteSourceFile: return SyncAction.DeleteSourceFile;//delete source file default: return SyncAction.CopyFileToTarget; } } else { return SyncAction.NoAction; } } else if (s.Equals(cFlag)) { if (t.Equals(cFlag)) { // Check Renaming. We suspect the two files has been renamed(i.e.contents are the same) if both of them // were marked as CREATE, so we need to check their contents. switch (_taskSettings.SrcTgtConflict) { case TaskSettings.ConflictSrcTgtAction.KeepBothCopies: if (sourceDirtyFile.Name.Equals(destDirtyFile.Name) && sourceDirtyFile.LastWriteTime.Equals(destDirtyFile.LastWriteTime) && sourceDirtyFile.Hash.Equals(destDirtyFile.Hash)) return SyncAction.NoAction; else return SyncAction.KeepBothCopies; case TaskSettings.ConflictSrcTgtAction.KeepLatestCopy: if (sourceDirtyFile.LastWriteTime.Equals(destDirtyFile.LastWriteTime) && sourceDirtyFile.Hash.Equals(destDirtyFile.Hash)) return SyncAction.KeepBothCopies; if (sourceDirtyFile.LastWriteTime > destDirtyFile.LastWriteTime) //keep the lastest file if two files are both modified { return SyncAction.CopyFileToTarget; } else { return SyncAction.CopyFileToSource; } case TaskSettings.ConflictSrcTgtAction.SourceOverwriteTarget: if (sourceDirtyFile.LastWriteTime.Equals(destDirtyFile.LastWriteTime) && sourceDirtyFile.Hash.Equals(destDirtyFile.Hash)) return SyncAction.KeepBothCopies; return SyncAction.CopyFileToTarget; case TaskSettings.ConflictSrcTgtAction.TargetOverwriteSource: if (sourceDirtyFile.LastWriteTime.Equals(destDirtyFile.LastWriteTime) && sourceDirtyFile.Hash.Equals(destDirtyFile.Hash)) return SyncAction.KeepBothCopies; return SyncAction.CopyFileToSource; default: return SyncAction.KeepBothCopies; } } else if (t.Equals(dFlag)) { switch (_taskSettings.SrcConflict) { case TaskSettings.ConflictSrcAction.CopyFileToTarget: return SyncAction.CopyFileToTarget;//copy source to destination case TaskSettings.ConflictSrcAction.DeleteSourceFile: return SyncAction.DeleteSourceFile;//delete source file default: return SyncAction.CopyFileToTarget; } } else if (t.Equals(rFlag) || t.Equals(mFlag)) { switch (_taskSettings.SrcTgtConflict) { case TaskSettings.ConflictSrcTgtAction.KeepBothCopies: return SyncAction.KeepBothCopies; case TaskSettings.ConflictSrcTgtAction.KeepLatestCopy: if (sourceDirtyFile.LastWriteTime > destDirtyFile.LastWriteTime) //keep the lastest file if two files are both modified { return SyncAction.CopyFileToTarget; } else { return SyncAction.CopyFileToSource; } case TaskSettings.ConflictSrcTgtAction.SourceOverwriteTarget: return SyncAction.CopyFileToTarget; case TaskSettings.ConflictSrcTgtAction.TargetOverwriteSource: return SyncAction.CopyFileToSource; default: return SyncAction.KeepBothCopies; } } else { return SyncAction.NoAction; } } else if (s.Equals(dFlag)) { if (t.Equals(cFlag) || t.Equals(mFlag)) { switch (_taskSettings.TgtConflict) { case TaskSettings.ConflictTgtAction.CopyFileToSource: return SyncAction.CopyFileToSource;//copy destination to source case TaskSettings.ConflictTgtAction.DeleteTargetFile: return SyncAction.DeleteTargetFile;//delete destination file default: return SyncAction.CopyFileToSource; } } else if (t.Equals(dFlag)) { return SyncAction.NoAction; } else { return SyncAction.NoAction; } } else return SyncAction.NoAction; }
private void CreateOldState(SyncTask curTask, TestCase t, string[] createFiles, CustomDictionary<string, string, FileUnit> srcMeta, int srcLength, CustomDictionary<string, string, FileUnit> tgtMeta, int tgtLength) { foreach (String file in createFiles) { FileInfo newFile = new FileInfo(curTask.Source + file.Trim()); if (!newFile.Directory.Exists) { #region Create directories Directory.CreateDirectory(newFile.DirectoryName); FileInfo newFileTgt = new FileInfo(curTask.Target + file.Trim()); Directory.CreateDirectory(newFileTgt.DirectoryName); if (t.Param1.Equals("Y")) { String tempSrc = newFile.DirectoryName + @"\"; String tempTgt = newFileTgt.DirectoryName + @"\"; srcMeta.Add(tempSrc.Substring(srcLength), new FileUnit(newFile.DirectoryName)); tgtMeta.Add(tempTgt.Substring(tgtLength), new FileUnit(newFileTgt.DirectoryName)); } #endregion } #region Create files StreamWriter sw = newFile.CreateText(); sw.Close(); File.Copy(curTask.Source + file.Trim(), curTask.Target + file.Trim()); Console.WriteLine("Creating file " + file.Trim() + " on _source and _target directory..."); #endregion if (t.Param1.Equals("Y")) { #region Add to metadata list FileUnit srcFileUnit = new FileUnit(curTask.Source + file.Trim()); FileUnit tgtFileUnit = new FileUnit(curTask.Target + file.Trim()); String temp = null; if (file.Trim().StartsWith(@"\")) temp = file.Trim().Substring(1); else temp = file; srcMeta.Add(temp.Trim(), Utility.ComputeMyHash(srcFileUnit), srcFileUnit); tgtMeta.Add(temp.Trim(), Utility.ComputeMyHash(tgtFileUnit), tgtFileUnit); #endregion } } }