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); }