/// <summary> /// /// </summary> /// <param name="parentFolder"></param> /// <param name="newFolderName"></param> /// <returns></returns> /// <exception cref="InsufficientSpaceException"></exception> /// <exception cref="MaximumFileSizeReachedException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FolderAlreadyExistsException"></exception> private FolderNode CreateFolder(FolderNode parentFolder, string newFolderName) { MethodArgumentValidator.ThrowIfNull(parentFolder, "parentFolder"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(newFolderName, "newFolderName"); var subfolders = _nodeResolver.GetAllFoldersFrom(parentFolder); var folderWithSameName = subfolders.FirstOrDefault(subfolder => _namesComparer.Equals(subfolder.Name, newFolderName)); if (folderWithSameName != null) { throw new FolderAlreadyExistsException("Подпапка с именем \"{0}\" уже существует в папке \"{1}\"".FormatWith(newFolderName, parentFolder.Name)); } var freeBlocks = _freeBlockManager.AcquireFreeBlocks(3); int blockToStoreFileReferencesIn = freeBlocks[0]; int blockToStoreFolderNodeIn = freeBlocks[1]; int blockToStoreSubfolderReferencesIn = freeBlocks[2]; var fileReferencesStreamDefinition = new DataStreamDefinition(blockToStoreFileReferencesIn, 0); var folderReferencesStreamDefinition = new DataStreamDefinition(blockToStoreSubfolderReferencesIn, 0); try { // Note: может стать последней каплей для переполненного диска, и тогда блоки придется отпустить _blockReferenceListsEditor.AddBlockReference(blockToStoreFolderNodeIn, parentFolder.FolderReferencesStreamDefinition, parentFolder); } catch (Exception) { _freeBlockManager.MarkBlocksAsFree(freeBlocks); throw; } var creationTime = DateTime.UtcNow; var newNode = new FolderNode(newFolderName, Guid.NewGuid(), blockToStoreFolderNodeIn, parentFolder.DiskBlockIndex, fileReferencesStreamDefinition, folderReferencesStreamDefinition, creationTime, Guid.NewGuid()); _fileSystemNodeStorage.WriteNode(newNode); return(newNode); }
/// <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); }
public void Format(IVirtualDisk virtualDisk, FileSystemNodeStorage fileSystemNodeStorage) { var numberOfBlocksToMap = virtualDisk.NumberOfBlocks - FileSystemHeaderReservedBlocks; int numberOfBytesNeededToStoreTheMap = SpaceRequirementsCalculator.GetNumberOfChunksNeededToStoreData(numberOfBlocksToMap, Constants.NumberOfBitsInByte); int numberOfBlocksNeededToStoreTheMap = SpaceRequirementsCalculator.GetNumberOfChunksNeededToStoreData(numberOfBytesNeededToStoreTheMap, virtualDisk.BlockSizeInBytes); numberOfBlocksToMap -= numberOfBlocksNeededToStoreTheMap; var freeSpaceBitmap = new BitArray(numberOfBytesNeededToStoreTheMap); freeSpaceBitmap.Length = numberOfBlocksToMap; var store = new FreeSpaceBitmapStore(virtualDisk, VirtualDiskFormatter.FreeSpaceStartingBlockIndex); var freeBlockManagerBitArrayBased = new FreeBlockManagerBitArrayBased(freeSpaceBitmap, FreeSpaceStartingBlockIndex + numberOfBlocksNeededToStoreTheMap, numberOfBlocksToMap); var freeBlockManager = new FreeBlockManagerDiskWriting(store, freeBlockManagerBitArrayBased); var freeBlocks = freeBlockManager.AcquireFreeBlocks(3); int rootBlockIndex = freeBlocks[0]; int rootFileReferencesBlock = freeBlocks[1]; int rootFolderReferencesBlock = freeBlocks[2]; var fileContentsStreamDefinition = new DataStreamDefinition(rootFileReferencesBlock, 0); var folderContentsStreamDefinition = new DataStreamDefinition(rootFolderReferencesBlock, 0); var rootNode = new FolderNode("root", Guid.NewGuid(), rootBlockIndex, 0, fileContentsStreamDefinition, folderContentsStreamDefinition, DateTime.UtcNow, Guid.NewGuid()); fileSystemNodeStorage.WriteNode(rootNode); fileSystemNodeStorage.WriteFileSystemHeader(new FileSystemHeader(rootBlockIndex, new Version(1, 0, 0, 0)), FileSystemHeaderBlockIndex); }