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; } }
private void InitializeVirtualFileSystem() { var virtualFileSystemPath = $"{AppDomain.CurrentDomain.BaseDirectory}{Configurations.FileSystemFileName}"; _virtualFileSystem = File.Exists(virtualFileSystemPath) ? VirtualFileSystem.VirtualFileSystem.LoadFromFile(virtualFileSystemPath) : CreateNewVirtualFileSystem(virtualFileSystemPath); }
// 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); } }
public Stream SeekableStream() => VirtualFileSystem.EnsureSeekable(GetStream(), Size);
/// <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())); }
/// <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); } }
/// <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()); }