public Task RunAsync(DirectoryInfo srcDir, DirectoryInfo dstDir, IFileInfoEqualityComparer fileInfoComparer, CancellationToken token) { if (srcDir == null) { throw new ArgumentNullException(nameof(srcDir)); } if (dstDir == null) { throw new ArgumentNullException(nameof(dstDir)); } if (fileInfoComparer == null) { throw new ArgumentNullException(nameof(fileInfoComparer)); } if (!srcDir.Exists) { throw new DirectoryNotFoundException("Source directory does not exist: " + srcDir.FullName + "."); } if (IsRunning) { throw new InvalidOperationException("DirectoryMirrorer is already running."); } _token = token; _task = Task.Run(() => InternalStart(srcDir, dstDir, fileInfoComparer)); return(_task); }
private void FindDuplicates(IFileInfoEqualityComparer fileComparer) { _files.Sort((x, y) => y.Length.CompareTo(x.Length)); var i = 0; while (i < _files.Count) { _token.ThrowIfCancellationRequested(); var start = i++; while (i < _files.Count && _files[start].Length == _files[i].Length) { i++; } var length = i - start; if (length > 1) { FindDuplicates(start, length, fileComparer); } OnFilesProcessed(start, length); } }
private void GetOperations(IFileInfoEqualityComparer fileInfoComparer) { while (_stack.Count > 0) { _token.ThrowIfCancellationRequested(); var index = _stack.Count; var srcDir = _stack[--index]; var dstDir = _stack[--index]; _stack.RemoveRange(index, 2); if (!AttributesEqual(srcDir.Attributes, dstDir.Attributes)) { OnOperationFound(new EditAttributesOperation(dstDir, srcDir.Attributes)); } GetDirectoryChanges(srcDir, dstDir, fileInfoComparer); if (_stack.Count > index) { _stack.Reverse(index, _stack.Count - index); } } }
private void GroupEqualFileInfosAtTop(int start, int length, IFileInfoEqualityComparer fileInfoComparer) { for (var i = 0; i < length;) { var equalFiles = 1; for (var j = i + 1; j < length; j++) { var f1 = _files[start + i]; var f2 = _files[start + j]; if (fileInfoComparer.Equals(f1, f2)) { equalFiles++; _files.Swap(start + i, start + j); } } if (equalFiles > 1) { OnDuplicateFound(start + i, equalFiles); } i += equalFiles; } }
private void FindDuplicates(int start, int length, IFileInfoEqualityComparer fileInfoComparer) { try { if (length == 2) { if (fileInfoComparer.Equals(_files[start], _files[start + 1])) { OnDuplicateFound(start, length); } } else { if (fileInfoComparer is IFileEqualityComprarer fileComparer) { new MultiFileEqualityComparer(this, start, length, fileComparer).FindDuplicates(); } else { GroupEqualFileInfosAtTop(start, length, fileInfoComparer); } } } catch (FileSystemInfoException ex) { OnError(ex); } }
private bool SetComparer(bool quickScan) { bool AssumeNTFS() { return(MessageBox.Show("Failed to detect destination file system. Would you like to perform a quick scan anyway on the assumption that the destination file system is NTFS?", "Unknown file system", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes); } if (quickScan) { var fileSystem = GetDestinationFileSystem(); if (fileSystem == null && !AssumeNTFS()) { return(false); } _fileInfoComparer = CreateQuickScanComparer(fileSystem); } else { _fileInfoComparer = new FileEqualityComparer(); } return(true); }
private void InternalStart(DirectoryInfo srcDir, DirectoryInfo dstDir, IFileInfoEqualityComparer fileInfoComparer) { if (dstDir.Exists) { _stack.Clear(); _stack.Add(dstDir); _stack.Add(srcDir); GetOperations(fileInfoComparer); } else { _copier.CopyDirectory(srcDir, dstDir); } }
private void GetDirectoryChanges(DirectoryInfo srcDir, DirectoryInfo dstDir, IFileInfoEqualityComparer fileInfoComparer) { BuildSourceLookup(srcDir); try { foreach (var dstFsi in dstDir.EnumerateFileSystemInfos()) { ProcessDestinationFileSystemInfo(dstFsi, fileInfoComparer); } } catch (Exception ex) when(ex is IOException || ex is UnauthorizedAccessException || ex is SecurityException) { OnError(new FileSystemInfoException(dstDir, ex)); } CopyRemainingFileSystemInfosTo(dstDir); }
public Task RunAsync(IEnumerable <DirectoryInfo> dirs, IFileInfoEqualityComparer fileInfoComparer, CancellationToken token) { if (dirs == null) { throw new ArgumentNullException(nameof(dirs)); } if (fileInfoComparer == null) { throw new ArgumentNullException(nameof(fileInfoComparer)); } if (IsRunning) { throw new InvalidOperationException("DuplicateFinder is already running."); } _token = token; _task = Task.Run(() => InternalStart(dirs, fileInfoComparer)); return(_task); }
private void ProcessDestinationFileSystemInfo(FileSystemInfo dstFsi, IFileInfoEqualityComparer fileInfoComparer) { var fsiExistsInSrc = _srcLookup.TryGetValue(dstFsi.Name, out var srcFsi); if (fsiExistsInSrc) { _srcLookup.Remove(dstFsi.Name); CompareFileSystenInfo(srcFsi, dstFsi, fileInfoComparer); } else { if (dstFsi is FileInfo dstFile) { OnOperationFound(new DeleteFileOperation(dstFile)); } else if (dstFsi is DirectoryInfo dstDir) { _deleter.DeleteDirectory(dstDir); } } }
public Task RunAsync(DirectoryInfo srcDir, DirectoryInfo dstDir, IFileInfoEqualityComparer fileInfoComparer) { return(RunAsync(srcDir, dstDir, fileInfoComparer, CancellationToken.None)); }
private void CompareFileSystenInfo(FileSystemInfo srcFsi, FileSystemInfo dstFsi, IFileInfoEqualityComparer fileInfoComparer) { if (srcFsi is FileInfo srcFile) { if (dstFsi is FileInfo dstFile) { try { if (!fileInfoComparer.Equals(srcFile, dstFile)) { OnOperationFound(new EditFileOperation(srcFile, dstFile)); } else if (!AttributesEqual(srcFile.Attributes, dstFile.Attributes)) { OnOperationFound(new EditAttributesOperation(dstFile, srcFile.Attributes)); } } catch (FileSystemInfoException ex) { OnError(ex); } } else if (dstFsi is DirectoryInfo dstDir) { _deleter.DeleteDirectory(dstDir); OnOperationFound(new CopyFileOperation(srcFile, new FileInfo(dstFsi.FullName))); } } else if (srcFsi is DirectoryInfo srcDir) { if (dstFsi is FileInfo dstFile) { OnOperationFound(new DeleteFileOperation(dstFile)); _copier.CopyDirectory(srcDir, new DirectoryInfo(dstFsi.FullName)); } else if (dstFsi is DirectoryInfo dstDir) { _stack.Add(srcDir); _stack.Add(dstDir); } } }
private void InternalStart(IEnumerable <DirectoryInfo> dirs, IFileInfoEqualityComparer fileComparer) { _files.Clear(); new FileInfoEnumerator(this).AddDirectories(dirs); FindDuplicates(fileComparer); }
public Task RunAsync(IEnumerable <DirectoryInfo> dirs, IFileInfoEqualityComparer fileInfoComparer) { return(RunAsync(dirs, fileInfoComparer, CancellationToken.None)); }
public DuplicateFinderTask(DuplicatesForm duplicatesForm) { _duplicatesForm = duplicatesForm; _finder = new DuplicateFileFinderEx(this); _fileInfoComparer = new FileEqualityComparer(); }