/// <summary> /// Перемещает файл в указанную папку. /// </summary> /// <param name="currentPathForFile">Полный путь (от корня) к файлу, который следует переместить.</param> /// <param name="pathToFolderThatMustContainTheFile">Полный путь к папке, в которую нужно переместить указанный файл (<paramref name="currentPathForFile"/>).</param> /// <returns>Описание перемещенного файла, взятое с учетом его нового местоположения.</returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="FileLockedException"></exception> /// <exception cref="FileAlreadyExistsException"></exception> /// <exception cref="FolderNotFoundException"></exception> /// <exception cref="MaximumFileCountReachedException"></exception> /// <exception cref="InsufficientSpaceException"></exception> public FileInfo MoveFile(string currentPathForFile, string pathToFolderThatMustContainTheFile) { MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(currentPathForFile, "currentPathForFile"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(pathToFolderThatMustContainTheFile, "pathToFolderThatMustContainTheFile"); try { var newParentNodeResolvingResult = _nodeResolver.ResolveFolderNodeByPath(pathToFolderThatMustContainTheFile); FolderNode filesNewHome = newParentNodeResolvingResult.ResolvedNode; string fileName; var currentParentFolder = _nodeResolver.ResolveParentFolderNodeByPath(currentPathForFile, out fileName); ReadOnlyCollection <FileNode> allFilesInTheFolder; FolderNode folderToRemoveFileFrom = currentParentFolder.ResolvedNode; FileNode fileToMove = this.ResolveFileNodeThrowingUserFriendlyErrors(currentPathForFile, currentParentFolder, fileName, "переместить", out allFilesInTheFolder); var allFilesInDestinationFolder = _nodeResolver.GetAllFilesFrom(filesNewHome); // перемещение в то место, где файл и так уже находится. if (newParentNodeResolvingResult.ResolvedNode.Id.Equals(currentParentFolder.ResolvedNode.Id)) { return(new FileInfo(allFilesInDestinationFolder.First(fileNode => _namesComparer.Equals(fileNode.Name, fileName)), currentPathForFile)); } if (allFilesInDestinationFolder.Any(fileNode => _namesComparer.Equals(fileNode.Name, fileName))) { throw new FileAlreadyExistsException("Перемещение файла невозможно: в папке \"{0}\" уже существует файл с именем \"{1}\"".FormatWith(pathToFolderThatMustContainTheFile, fileName)); } // сначала добавляем ссылку в новую папку, потом удаляем ссылку из старой (на добавление может не хватить места, удалить же можно всегда). _blockReferenceListsEditor.AddBlockReference(fileToMove.DiskBlockIndex, filesNewHome.FileReferencesStreamDefinition, filesNewHome); // TODO: поглядеть на исключения этого метода. _blockReferenceListsEditor.TakeOutABlockFromBlockReferenceList(folderToRemoveFileFrom, fileToMove.DiskBlockIndex, folderToRemoveFileFrom.FileReferencesStreamDefinition); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(newParentNodeResolvingResult.FoldersPassedWhileResolving); _folderEnumeratorRegistry.InvalidateEnumeratorsForFolder(newParentNodeResolvingResult.ResolvedNode.Id); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(currentParentFolder.FoldersPassedWhileResolving); _folderEnumeratorRegistry.InvalidateEnumeratorsForFolder(currentParentFolder.ResolvedNode.Id); allFilesInDestinationFolder = _nodeResolver.GetAllFilesFrom(filesNewHome); return(new FileInfo( allFilesInDestinationFolder.Single(fileNode => _namesComparer.Equals(fileNode.Name, fileName)), _pathBuilder.CombinePaths(pathToFolderThatMustContainTheFile, fileName))); } catch (InsufficientSpaceException) { throw new InsufficientSpaceException("Не удалось переместить файл из \"{0}\" в \"{1}\" - не хватает места на диске для проведения операции.".FormatWith(currentPathForFile, pathToFolderThatMustContainTheFile)); } catch (MaximumFileSizeReachedException) { throw new MaximumFileCountReachedException("Не удалось переместить файл \"{0}\". Папка \"{1}\" не может вместить больше файлов, чем уже вмещает".FormatWith(currentPathForFile, pathToFolderThatMustContainTheFile)); } catch (CannotResolvePathException exception) { throw new FolderNotFoundException("Не удалось найти папку, где находится перемещаемый файл, или папку, в которую его следует переместить. {0}".FormatWith(exception.Message)); } catch (InvalidPathException exception) { throw new FolderNotFoundException("Не удалось найти папку, где находится перемещаемый файл, или папку, в которую его следует переместить. {0}".FormatWith(exception.Message)); } }
/// <summary> /// Перемещает папку в указанную директорию. /// </summary> /// <param name="currentPathForFolder">Полный путь (от корня) к папке, которую следует переместить.</param> /// <param name="pathToFolderThatWillContainTheFolderMoved">Полный путь к папке, в которую нужно переместить указанную директорию (<paramref name="currentPathForFolder"/>).</param> /// <returns>Описание перемещенной папки, взятое с учетом ее нового местоположения.</returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FolderLockedException"></exception> /// <exception cref="FolderAlreadyExistsException"></exception> /// <exception cref="FolderNotFoundException"></exception> /// <exception cref="MaximumFolderCountReachedException"></exception> /// <exception cref="InsufficientSpaceException"></exception> /// <exception cref="InvalidOperationException">Если пытаетесь переместить папку в одну из ее собственных поддиректорий.</exception> public FolderInfo MoveFolder(string currentPathForFolder, string pathToFolderThatWillContainTheFolderMoved) { MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(currentPathForFolder, "cucurrentPathForFolderrrentPathForFile"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(pathToFolderThatWillContainTheFolderMoved, "pathToFolderThatWillContainTheFolderMoved"); try { var newParentNodeResolvingResult = _nodeResolver.ResolveFolderNodeByPath(pathToFolderThatWillContainTheFolderMoved); FolderNode foldersNewHome = newParentNodeResolvingResult.ResolvedNode; string folderName; var currentParentFolder = _nodeResolver.ResolveParentFolderNodeByPath(currentPathForFolder, out folderName); FolderNode folderToRemoveDirectoryFrom = currentParentFolder.ResolvedNode; var directoriesInFolder = _nodeResolver.GetAllFoldersFrom(folderToRemoveDirectoryFrom); FolderNode folderToMove = directoriesInFolder.FirstOrDefault(fileNode => _namesComparer.Equals(fileNode.Name, folderName)); if (folderToMove == null) { throw new FolderNotFoundException("Не найдена папка для перемещения (\"{0}\")".FormatWith(currentPathForFolder)); } if (newParentNodeResolvingResult.FoldersPassedWhileResolving.Any(folderNode => folderNode.Id.Equals(folderToMove.Id))) { throw new InvalidOperationException("Операция перемещения папки \"{0}\" в \"{1}\" отменена: невозможно переместить папку в одну из ее же поддиректорий.".FormatWith(currentPathForFolder, pathToFolderThatWillContainTheFolderMoved)); } if (_lockingManager.IsNodeLockedForRenamesAndMoves(folderToMove)) { throw new FolderLockedException("Не удалось переместить папку (\"{0}\"): она или любая из ее поддиректорий содержит файлы открытые сейчас для чтения или записи.".FormatWith(currentPathForFolder)); } var allSubfoldersOfDestinationFolder = _nodeResolver.GetAllFoldersFrom(foldersNewHome); var idsOfAllSubfolders = _nodeResolver.GetIdsOfAllFoldersUnderGivenOne(currentPathForFolder); // перемещение в то место, где файл и так уже находится.) if (newParentNodeResolvingResult.ResolvedNode.Id.Equals(currentParentFolder.ResolvedNode.Id)) { return(new FolderInfo(allSubfoldersOfDestinationFolder.First(fileNode => _namesComparer.Equals(fileNode.Name, folderName)), currentPathForFolder)); } if (allSubfoldersOfDestinationFolder.Any(fileNode => _namesComparer.Equals(fileNode.Name, folderName))) { throw new FolderAlreadyExistsException("Перемещение папки невозможно: в директории \"{0}\" уже существует папка с именем \"{1}\"".FormatWith(pathToFolderThatWillContainTheFolderMoved, folderName)); } // сначала добавляем ссылку в новую папку, потом удаляем ссылку из старой (на добавление может не хватить места, удалить же можно всегда). _blockReferenceListsEditor.AddBlockReference(folderToMove.DiskBlockIndex, foldersNewHome.FolderReferencesStreamDefinition, foldersNewHome); // TODO: поглядеть на исключения этого метода. _blockReferenceListsEditor.TakeOutABlockFromBlockReferenceList(folderToRemoveDirectoryFrom, folderToMove.DiskBlockIndex, folderToRemoveDirectoryFrom.FolderReferencesStreamDefinition); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(newParentNodeResolvingResult.FoldersPassedWhileResolving); _folderEnumeratorRegistry.InvalidateEnumeratorsForFolder(newParentNodeResolvingResult.ResolvedNode.Id); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(currentParentFolder.FoldersPassedWhileResolving); _folderEnumeratorRegistry.InvalidateEnumeratorsForFolder(currentParentFolder.ResolvedNode.Id); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(idsOfAllSubfolders); allSubfoldersOfDestinationFolder = _nodeResolver.GetAllFoldersFrom(foldersNewHome); return(new FolderInfo( allSubfoldersOfDestinationFolder.Single(folderNode => _namesComparer.Equals(folderNode.Name, folderName)), _pathBuilder.CombinePaths(pathToFolderThatWillContainTheFolderMoved, folderName))); } catch (InsufficientSpaceException) { throw new InsufficientSpaceException("Не удалось переместить папку из \"{0}\" в \"{1}\" - не хватает места на диске для проведения операции.".FormatWith(currentPathForFolder, pathToFolderThatWillContainTheFolderMoved)); } catch (MaximumFileSizeReachedException) { throw new MaximumFolderCountReachedException("Не удалось переместить папку \"{0}\". Папка \"{1}\" не может вместить больше файлов, чем уже вмещает".FormatWith(currentPathForFolder, pathToFolderThatWillContainTheFolderMoved)); } catch (CannotResolvePathException exception) { throw new FolderNotFoundException("Не удалось найти папку, где находится перемещаемый файл, или папку, в которую его следует переместить. {0}".FormatWith(exception.Message)); } catch (InvalidPathException exception) { throw new FolderNotFoundException("Не удалось найти папку, где находится перемещаемый файл, или папку, в которую его следует переместить. {0}".FormatWith(exception.Message)); } }