Example #1
0
        public TransferMode TransferFolder(string sourcePath, string targetPath, TransferMode mode, DiskTransferVerificationMode verificationMode)
        {
            Ensure.That(sourcePath, () => sourcePath).IsValidPath();
            Ensure.That(targetPath, () => targetPath).IsValidPath();

            if (mode == TransferMode.Move && !_diskProvider.FolderExists(targetPath))
            {
                if (verificationMode == DiskTransferVerificationMode.TryTransactional || verificationMode == DiskTransferVerificationMode.VerifyOnly)
                {
                    var sourceMount = _diskProvider.GetMount(sourcePath);
                    var targetMount = _diskProvider.GetMount(targetPath);

                    // If we're on the same mount, do a simple folder move.
                    if (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory)
                    {
                        _logger.Debug("Move Directory [{0}] > [{1}]", sourcePath, targetPath);
                        _diskProvider.MoveFolder(sourcePath, targetPath);
                        return(mode);
                    }
                }
            }

            if (!_diskProvider.FolderExists(targetPath))
            {
                _diskProvider.CreateFolder(targetPath);

                _diskProvider.CopyPermissions(sourcePath, targetPath);
            }

            var result = mode;

            foreach (var subDir in _diskProvider.GetDirectoryInfos(sourcePath))
            {
                if (ShouldIgnore(subDir))
                {
                    continue;
                }

                result &= TransferFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name), mode, verificationMode);
            }

            foreach (var sourceFile in _diskProvider.GetFileInfos(sourcePath))
            {
                if (ShouldIgnore(sourceFile))
                {
                    continue;
                }

                var destFile = Path.Combine(targetPath, sourceFile.Name);

                result &= TransferFile(sourceFile.FullName, destFile, mode, true, verificationMode);
            }

            if (mode.HasFlag(TransferMode.Move))
            {
                _diskProvider.DeleteFolder(sourcePath, true);
            }

            return(result);
        }
        public TransferMode TransferFolder(string sourcePath, string targetPath, TransferMode mode)
        {
            Ensure.That(sourcePath, () => sourcePath).IsValidPath();
            Ensure.That(targetPath, () => targetPath).IsValidPath();

            sourcePath = ResolveRealParentPath(sourcePath);
            targetPath = ResolveRealParentPath(targetPath);

            _logger.Debug("{0} Directory [{1}] > [{2}]", mode, sourcePath, targetPath);

            if (sourcePath == targetPath)
            {
                throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
            }

            if (mode == TransferMode.Move && sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase) && _diskProvider.FolderExists(targetPath))
            {
                // Move folder out of the way to allow case-insensitive renames
                var tempPath = sourcePath + ".backup~";
                _logger.Trace("Rename Intermediate Directory [{0}] > [{1}]", sourcePath, tempPath);
                _diskProvider.MoveFolder(sourcePath, tempPath);

                if (!_diskProvider.FolderExists(targetPath))
                {
                    _logger.Trace("Rename Intermediate Directory [{0}] > [{1}]", tempPath, targetPath);
                    _logger.Debug("Rename Directory [{0}] > [{1}]", sourcePath, targetPath);
                    _diskProvider.MoveFolder(tempPath, targetPath);
                    return(mode);
                }

                // There were two separate folders, revert the intermediate rename and let the recursion deal with it
                _logger.Trace("Rename Intermediate Directory [{0}] > [{1}]", tempPath, sourcePath);
                _diskProvider.MoveFolder(tempPath, sourcePath);
            }

            if (mode == TransferMode.Move && !_diskProvider.FolderExists(targetPath))
            {
                var sourceMount = _diskProvider.GetMount(sourcePath);
                var targetMount = _diskProvider.GetMount(targetPath);

                // If we're on the same mount, do a simple folder move.
                if (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory)
                {
                    _logger.Debug("Rename Directory [{0}] > [{1}]", sourcePath, targetPath);
                    _diskProvider.MoveFolder(sourcePath, targetPath);
                    return(mode);
                }
            }

            if (!_diskProvider.FolderExists(targetPath))
            {
                _diskProvider.CreateFolder(targetPath);

                _diskProvider.CopyPermissions(sourcePath, targetPath);
            }

            var result = mode;

            foreach (var subDir in _diskProvider.GetDirectoryInfos(sourcePath))
            {
                if (ShouldIgnore(subDir))
                {
                    continue;
                }

                result &= TransferFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name), mode);
            }

            foreach (var sourceFile in _diskProvider.GetFileInfos(sourcePath))
            {
                if (ShouldIgnore(sourceFile))
                {
                    continue;
                }

                var destFile = Path.Combine(targetPath, sourceFile.Name);

                result &= TransferFile(sourceFile.FullName, destFile, mode, true);
            }

            if (mode.HasFlag(TransferMode.Move))
            {
                var totalSize = _diskProvider.GetFileInfos(sourcePath).Sum(v => v.Length);

                if (totalSize > (100 * 1024L * 1024L))
                {
                    throw new IOException($"Large files still exist in {sourcePath} after folder move, not deleting source folder");
                }

                _diskProvider.DeleteFolder(sourcePath, true);
            }

            return(result);
        }