コード例 #1
0
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FileAlreadyExistsException"></exception>
        /// <exception cref="NoFreeBlocksException"></exception>
        /// <exception cref="InsufficientSpaceException"></exception>
        /// <exception cref="MaximumFileSizeReachedException"></exception>
        private FileNode CreateFile(FolderNode parentFolder, string fileName)
        {
            MethodArgumentValidator.ThrowIfNull(parentFolder, "parentFolder");
            MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(fileName, "fileName");

            var filesInTheFolder = _nodeResolver.GetAllFilesFrom(parentFolder);

            var fileWithSameName = filesInTheFolder.FirstOrDefault(file => _namesComparer.Equals(file.Name, fileName));

            if (fileWithSameName != null)
            {
                throw new FileAlreadyExistsException("Файл с именем \"{0}\" уже существует в папке \"{1}\"".FormatWith(fileName, parentFolder.Name));
            }

            var freeBlocks = _freeBlockManager.AcquireFreeBlocks(2);

            int blockToStoreDefinitionIn = freeBlocks[0];
            int blockToStoreFileNodeIn   = freeBlocks[1];

            var fileContentsStreamDefinition = new DataStreamDefinition(blockToStoreDefinitionIn, 0);

            try
            {
                // Note: это добавление ссылки может стать последней каплей для заполненного диска, тогда блоки придется отпустить
                _blockReferenceListsEditor.AddBlockReference(blockToStoreFileNodeIn, parentFolder.FileReferencesStreamDefinition, parentFolder);
            }
            catch (Exception)
            {
                _freeBlockManager.MarkBlocksAsFree(freeBlocks);

                throw;
            }

            var creationTime = DateTime.UtcNow;

            var fileNode = new FileNode(fileName, Guid.NewGuid(), blockToStoreFileNodeIn, fileContentsStreamDefinition, creationTime, creationTime, Guid.NewGuid());

            _fileSystemNodeStorage.WriteNode(fileNode);

            return(fileNode);
        }
コード例 #2
0
        /// <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));
            }
        }