/// <summary> /// Удаляет указанный файл. /// </summary> /// <param name="filePath">Путь, указывающий удаляемый файл.</param> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="FileLockedException"></exception> /// <exception cref="InvalidPathException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ObjectDisposedException"></exception> public void DeleteFile(string filePath) { MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(filePath, "filePath"); if (_pathBuilder.PointsToRoot(filePath)) { throw new InvalidPathException("Не получилось удалить файл: нельзя удалить корень файловой системы."); } try { string fileName; var parentFolderResolvingResult = _nodeResolver.ResolveParentFolderNodeByPath(filePath, out fileName); ReadOnlyCollection <FileNode> files; FolderNode folderToRemoveFileFrom = parentFolderResolvingResult.ResolvedNode; FileNode fileToRemove = ResolveFileNodeThrowingUserFriendlyErrors(filePath, parentFolderResolvingResult, fileName, "удалить", out files); // очистка всех данных. using (var dataStream = this.OpenFileForWriting(filePath)) { dataStream.Truncate(); } // TODO: поглядеть на исключения этого метода. _blockReferenceListsEditor.TakeOutABlockFromBlockReferenceList(folderToRemoveFileFrom, fileToRemove.DiskBlockIndex, folderToRemoveFileFrom.FileReferencesStreamDefinition); _freeBlockManager.MarkBlockAsFree(fileToRemove.DiskBlockIndex); _freeBlockManager.MarkBlockAsFree(fileToRemove.FileContentsStreamDefinition.ContentsBlockIndex); _folderEnumeratorRegistry.InvalidateEnumeratorsFor(parentFolderResolvingResult.FoldersPassedWhileResolving); _folderEnumeratorRegistry.InvalidateEnumeratorsForFolder(parentFolderResolvingResult.ResolvedNode.Id); } catch (CannotResolvePathException) { throw new FileNotFoundException("Не удалось найти файл {0}".FormatWith(filePath)); } catch (InvalidPathException) { throw new FileNotFoundException("Не удалось найти файл {0}".FormatWith(filePath)); } }
/// <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)); } }