/// <summary> /// /// </summary> /// <param name="fileSystem"></param> /// <param name="exportingFolderPath"></param> /// <param name="virtualDestinationFolder"></param> /// <param name="taskToken"></param> /// <returns></returns> /// <exception cref="InsufficientSpaceException"></exception> /// <exception cref="CannotGetImportedFolderStructureException"></exception> /// <exception cref="FolderNotFoundException"></exception> internal static ReadOnlyCollection <FileSystemTaskResult> ImportFolderFromRealFileSystem( this VirtualFileSystem fileSystem, string exportingFolderPath, string virtualDestinationFolder, IFileSystemCancellableTaskToken taskToken) { if (fileSystem == null) { throw new ArgumentNullException("fileSystem"); } MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(exportingFolderPath, "exportingFolderPath"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(virtualDestinationFolder, "virtualDestinationFolder"); FolderAddressable folderAddressable = CreateFileSystemObjectStructureFromFolder(exportingFolderPath); int totalNumberOfFilesToTraverse = folderAddressable.GetTotalFileCount(); // Note: можно уменьшить связность классов, передав сюда через интерфейс фабрику, которая уж знает, как сделать нужного Visitor-а. ImportingAddressableObjectVisitor visitor = new ImportingAddressableObjectVisitor(fileSystem, exportingFolderPath, virtualDestinationFolder, new RealFileContentsBufferFactory(), taskToken, totalNumberOfFilesToTraverse); if (!fileSystem.FolderExists(virtualDestinationFolder)) { throw new FolderNotFoundException("Не удалось найти папку \"{0}\", в которую следует произвести копирование/импорт.".FormatWith(virtualDestinationFolder)); } folderAddressable.Accept(visitor); var results = visitor.GetResult(); return(results); }
/// <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); } }
internal FolderTaskResult(FolderAddressable sourceFolderPath, FolderAddressable destinationFolderPath, string error) : base(error) { if (sourceFolderPath == null) { throw new ArgumentNullException("sourceFolderPath"); } if (!String.IsNullOrEmpty(error) && (destinationFolderPath != null)) { throw new ArgumentException("Если установлено сообщение об ошибке, значит указателя на папку быть не может.", "destinationFolderPath"); } SourceFolder = sourceFolderPath; DestinationFolder = destinationFolderPath; }
/// <summary> /// /// </summary> /// <param name="folderPath"></param> /// <returns></returns> /// <exception cref="CannotGetImportedFolderStructureException"></exception> private static FolderAddressable CreateFileSystemObjectStructureFromFolder(string folderPath) { try { System.IO.DirectoryInfo di = new DirectoryInfo(folderPath); IEnumerable <FileAddressable> files = di.GetFiles().Select(fileInfo => new FileAddressable(fileInfo.FullName, fileInfo.Name)); var subfolders = new List <FolderAddressable>(); DirectoryInfo[] folders = di.GetDirectories(); foreach (DirectoryInfo directoryInfo in folders) { try { FolderAddressable folderInfo = CreateFileSystemObjectStructureFromFolder(directoryInfo.FullName); subfolders.Add(folderInfo); } catch (DirectoryNotFoundException) // уже удалили? что ж - ничего страшного. Точнее, для простоты я говорю: "Ничего страшного". В общем случае это вопрос для обсуждения. { } } return(new FolderAddressable(di.FullName, di.Name, subfolders, files)); } catch (DirectoryNotFoundException) { throw new CannotGetImportedFolderStructureException("Не удалось проимпортиовать содержимое \"{0}\" - такой папки не существует.".FormatWith(folderPath)); } catch (IOException exception) // увы, XML-комментарии относительно исключений в классах .Net FW точны далеко не всегда. { throw CreateGenericStructureCreationError(folderPath, exception); } catch (SecurityException exception) { throw new CannotGetImportedFolderStructureException("Не удалось проимпортиовать содержимое \"{0}\". Убедитесь, что у вашей учетной записи есть права доступа к папке и всем ее подпапкам. Далее - точные сведения об ошибке.{1}{2}".FormatWith(folderPath, Environment.NewLine, exception.Message)); } catch (ArgumentException exception) { throw CreateGenericStructureCreationError(folderPath, exception); } }