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);
     }
 }
Beispiel #6
0
            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();
 }