Beispiel #1
0
        /// <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));
            }
        }
        public static void InvalidateEnumeratorsFor(this IFolderEnumeratorRegistry enumeratorRegistry, IEnumerable <Guid> idsOfFolders)
        {
            if (enumeratorRegistry == null)
            {
                throw new ArgumentNullException("enumeratorRegistry");
            }
            if (idsOfFolders == null)
            {
                throw new ArgumentNullException("idsOfFolders");
            }

            foreach (Guid id in idsOfFolders)
            {
                enumeratorRegistry.InvalidateEnumeratorsForFolder(id);
            }
        }
        public static void InvalidateEnumeratorsFor(this IFolderEnumeratorRegistry enumeratorRegistry, IEnumerable <FolderNode> folders)
        {
            if (enumeratorRegistry == null)
            {
                throw new ArgumentNullException("enumeratorRegistry");
            }
            if (folders == null)
            {
                throw new ArgumentNullException("folders");
            }

            foreach (FolderNode folderNode in folders)
            {
                enumeratorRegistry.InvalidateEnumeratorsForFolder(folderNode.Id);
            }
        }
        /// <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));
            }
        }