Example #1
0
        public static IFileSystem CreateNewVolume([NotNull] string fileName, ulong volumeSize, [NotNull] IFileSystem destination)
        {
            Validate.ArgumentNotNull(fileName, "fileName");
            Validate.ArgumentNotNull(destination, "destination");

            var file = destination.CreateFile(fileName);
            file.SetFileSize(volumeSize); // preliminary allocation. mounting system will increase this size slightly.

            if (destination is PhysicalFileSystem)
            {
                var stream = new VirtualStream(file);
                var diskAccess = new DirectDiskAccess(stream);
                var vfs = new VirtualFileSystem(diskAccess, volumeSize);
                file.SetFileSize(vfs.RealVolumeSize);
                return vfs;
            }
            else
            {
                // for virtual files mounting file system directly.
                // this allows parallel access from any thread, not restricted by writer lock in creating thread.
                var destVfs = (VirtualFileSystem)destination;
                file.Close();
                var diskAccess = destVfs.MountDisk(fileName);
                var vfs = new VirtualFileSystem(diskAccess, volumeSize);
                diskAccess.SetFileSize(vfs.RealVolumeSize);
                return vfs;
            }
        }
Example #2
0
        private void InitializeVirtualFileSystem()
        {
            var virtualFileSystemPath = $"{AppDomain.CurrentDomain.BaseDirectory}{Configurations.FileSystemFileName}";

            _virtualFileSystem = File.Exists(virtualFileSystemPath)
                ? VirtualFileSystem.VirtualFileSystem.LoadFromFile(virtualFileSystemPath)
                : CreateNewVirtualFileSystem(virtualFileSystemPath);
        }
Example #3
0
        // Note: этот код специально прилеплен к и без того немаленькому VirtualFileSystem. Это повышает discoverability фабричных методов (по сравнению с выделением фабрики) и усиливает ограничения (private-конструктор против internal-конструктора).

        /// <summary>
        /// Создает виртуальную файловую систему с настройками по умолчанию, на основе указанного файла.
        /// </summary>
        /// <param name="fullPathForFile"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FileSystemCreationFailedException"></exception>
        public static VirtualFileSystem OpenExisting(string fullPathForFile)
        {
            if (String.IsNullOrEmpty(fullPathForFile))
            {
                throw new ArgumentNullException("fullPathForFile");
            }

            FileStream stream = CreateStreamFromExistingFileWrappingExceptions(fullPathForFile);

            try
            {
                VirtualDisk disk = VirtualDisk.CreateFromStream(stream);

                var diskStructuresManager = new FileSystemNodeStorage(disk);

                FileSystemHeader header = diskStructuresManager.ReadFileSystemHeader(VirtualDiskFormatter.FileSystemHeaderBlockIndex);

                var nameValidator = FileSystemArtifactNamesValidator.Default;

                var pathValidator = PathValidator.Default;

                var pathBuilder = PathBuilder.Default;

                var nodeResolver = new NodeResolver(disk, diskStructuresManager, StringComparer.OrdinalIgnoreCase, header.RootBlockOffset, VirtualFileSystem.Root, VirtualFileSystem.DirectorySeparatorChar, pathValidator, pathBuilder);

                return(VirtualFileSystem.CreateFromDisk(disk, StringComparer.OrdinalIgnoreCase, nodeResolver, pathBuilder, nameValidator, pathValidator));
            }
            catch (VirtualDiskCreationFailedException exception)
            {
                throw CreateGenericSystemCreationFromExistingFileException(exception, fullPathForFile);
            }
            catch (InconsistentDataDetectedException exception)
            {
                throw CreateGenericSystemCreationFromExistingFileException(exception, fullPathForFile);
            }
        }
Example #4
0
 public Stream SeekableStream() => VirtualFileSystem.EnsureSeekable(GetStream(), Size);
Example #5
0
 /// <summary>
 /// Импортирует содержимое указанной папки в виртуальной файловой системе компьютера в другую виртуальную файловую систему.
 /// </summary>
 /// <param name="destinationFileSystem">Виртуальная файловая система, в которую надо проимпортировать данные.</param>
 /// <param name="sourceVirtualSystem">Виртуальная файловая система, в которую надо импортировать данные.</param>
 /// <param name="exportingFolderPath">Папка в виртуальной файловой системе компьютера, откуда следует проэкспортиовать данные.</param>
 /// <param name="virtualDestinationFolder">Папка, в которую следует проимпортировать содержимое <paramref name="exportingFolderPath"/>.</param>
 /// <returns>Объекты, показывающие результат импорта каждой папок, каждого из файлов.</returns>
 /// <exception cref="InsufficientSpaceException"></exception>
 /// <exception cref="CannotGetImportedFolderStructureException"></exception>
 public static ReadOnlyCollection <FileSystemTaskResult> ImportFolderFromVirtualFileSystem(this VirtualFileSystem destinationFileSystem, VirtualFileSystem sourceVirtualSystem, string exportingFolderPath, string virtualDestinationFolder)
 {
     return(ImportFolderFromVirtualFileSystem(destinationFileSystem, sourceVirtualSystem, exportingFolderPath,
                                              virtualDestinationFolder, new NullFileSystemCancellableTaskToken()));
 }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourceVirtualSystem"></param>
        /// <param name="folderPath"></param>
        /// <returns></returns>
        /// <exception cref="CannotGetImportedFolderStructureException"></exception>
        private static FolderAddressable CreateFileSystemObjectStructureFromVirtualFolder(VirtualFileSystem sourceVirtualSystem, string folderPath)
        {
            try
            {
                // TODO: логично сделать построение дерева атомарной операцией файловой системы. Делать я этого не стану - для простоты.
                IEnumerable <FileAddressable> files =
                    ((IFilesAndFoldersProvider)sourceVirtualSystem).GetAllFilesFrom(folderPath).Select(fileInfo => new FileAddressable(fileInfo.FullPath, fileInfo.Name));

                var subfolders = new List <FolderAddressable>();

                var folders = sourceVirtualSystem.GetAllFoldersFrom(folderPath);

                foreach (FolderInfo directoryInfo in folders)
                {
                    try
                    {
                        FolderAddressable folderInfo = CreateFileSystemObjectStructureFromVirtualFolder(sourceVirtualSystem, directoryInfo.FullPath);
                        subfolders.Add(folderInfo);
                    }
                    catch (FolderNotFoundException)
                    {
                    }
                }

                return(new FolderAddressable(folderPath, sourceVirtualSystem.PathBuilder.GetFileOrFolderName(folderPath), subfolders, files));
            }
            catch (FolderNotFoundException exception)
            {
                throw new CannotGetImportedFolderStructureException("Не удалось проимпортиовать/скопировать содержимое \"{0}\" - такой папки не существует.".FormatWith(folderPath), exception);
            }
            catch (ObjectDisposedException exception)
            {
                throw new CannotGetImportedFolderStructureException("Не удалось проимпортиовать/скопировать содержимое \"{0}\" - экземпляр виртуальной файловой системы был закрыт явным вызовом Dispose().".FormatWith(folderPath), exception);
            }
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="destinationFileSystem"></param>
        /// <param name="sourceVirtualSystem"></param>
        /// <param name="exportingFolderPath"></param>
        /// <param name="virtualDestinationFolder"></param>
        /// <param name="taskToken"></param>
        /// <returns></returns>
        /// <exception cref="CannotGetImportedFolderStructureException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InsufficientSpaceException"></exception>
        /// <exception cref="FolderNotFoundException"></exception>
        internal static ReadOnlyCollection <FileSystemTaskResult> ImportFolderFromVirtualFileSystem(this VirtualFileSystem destinationFileSystem, VirtualFileSystem sourceVirtualSystem, string exportingFolderPath, string virtualDestinationFolder, IFileSystemCancellableTaskToken taskToken)
        {
            if (destinationFileSystem == null)
            {
                throw new ArgumentNullException("destinationFileSystem");
            }
            if (sourceVirtualSystem == null)
            {
                throw new ArgumentNullException("sourceVirtualSystem");
            }

            FolderAddressable folderAddressable = CreateFileSystemObjectStructureFromVirtualFolder(sourceVirtualSystem, exportingFolderPath);

            int totalNumberOfFilesToTraverse = folderAddressable.GetTotalFileCount();

            // Note: можно уменьшить связность классов, передав сюда через интерфейс фабрику, которая уж знает, как сделать нужного Visitor-а.

            var visitor = new ImportingAddressableObjectVisitor(destinationFileSystem, exportingFolderPath, virtualDestinationFolder,
                                                                new VirtualFileContentsBufferFactory(sourceVirtualSystem), taskToken, totalNumberOfFilesToTraverse);

            if (!destinationFileSystem.FolderExists(virtualDestinationFolder))
            {
                throw new FolderNotFoundException("Не удалось найти папку \"{0}\", в которую следует произвести копирование/импорт.".FormatWith(virtualDestinationFolder));
            }

            folderAddressable.Accept(visitor);
            return(visitor.GetResult());
        }