Example #1
0
        /// <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);
        }
Example #2
0
        public ImportingAddressableObjectVisitor(
            VirtualFileSystem targetFileSystem,
            string sourceFolderPath,
            string destinationFolder,
            IFileContentsBufferFactory fileContentsBufferFactory,
            IFileSystemCancellableTaskToken taskToken,
            int totalNumberOfFilesToVisit)
        {
            if (targetFileSystem == null)
            {
                throw new ArgumentNullException("targetFileSystem");
            }
            if (sourceFolderPath == null)
            {
                throw new ArgumentNullException("sourceFolderPath");
            }
            if (destinationFolder == null)
            {
                throw new ArgumentNullException("destinationFolder");
            }
            if (fileContentsBufferFactory == null)
            {
                throw new ArgumentNullException("fileContentsBufferFactory");
            }
            if (taskToken == null)
            {
                throw new ArgumentNullException("taskToken");
            }

            _targetFileSystem          = targetFileSystem;
            _sourceFolderPath          = sourceFolderPath;
            _destinationFolder         = destinationFolder;
            _fileContentsBufferFactory = fileContentsBufferFactory;
            _taskToken = taskToken;
            _totalNumberOfFilesToVisit = totalNumberOfFilesToVisit;
        }
Example #3
0
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="FileLockedException"></exception>
        /// <exception cref="ObjectDisposedException"></exception>
        /// <exception cref="InvalidPathException"></exception>
        /// <exception cref="FolderNotFoundException"></exception>
        /// <exception cref="FileAlreadyExistsException"></exception>
        /// <exception cref="InsufficientSpaceException"></exception>
        /// <exception cref="MaximumFileCountReachedException"></exception>
        /// <exception cref="MaximumFileSizeReachedException"></exception>
        /// <exception cref="TaskCancelledException"></exception>
        private void CopyFileContents(IFileSystemCancellableTaskToken taskToken, string fullPathForFileToBeCopied, string newPathThatWillPointToTheCopyOfFile)
        {
            using (var readingStream = this.OpenFileForReading(fullPathForFileToBeCopied))
            {
                double totalNumberOfBytesToWrite = readingStream.Length;
                int    percentage           = 0;
                double numberOfBytesWritten = 0;

                var buffer = new byte[FileCopyingBufferSizeInBytes];

                using (var writingStream = this.CreateAndOpenFileForWriting(newPathThatWillPointToTheCopyOfFile))
                {
                    int numberOfBytesRead;

                    while ((numberOfBytesRead = readingStream.Read(buffer, 0, FileCopyingBufferSizeInBytes)) != 0)
                    {
                        writingStream.Write(buffer, 0, numberOfBytesRead);

                        numberOfBytesWritten += numberOfBytesRead;

                        int newPercentage = (int)((numberOfBytesWritten / totalNumberOfBytesToWrite) * 100);

                        if (newPercentage != percentage)
                        {
                            percentage = newPercentage;
                            taskToken.ReportProgressChange(newPercentage);
                        }

                        if (taskToken.HasBeenCancelled)
                        {
                            throw new TaskCancelledException("Задача снята");
                        }
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// Копирует указанный файл.
        /// </summary>
        /// <param name="fullPathForFileToBeCopied">Полный путь (от корня), указывающий файл, который следует скопировать.</param>
        /// <param name="newPathThatWillPointToTheCopyOfFile">Полный путь (от корня), указывающий, где будет находиться и как называться копия файла.</param>
        /// <param name="taskToken"></param>
        /// <returns>Описание копии файла.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="FileLockedException"></exception>
        /// <exception cref="ObjectDisposedException"></exception>
        /// <exception cref="InvalidPathException"></exception>
        /// <exception cref="FolderNotFoundException"></exception>
        /// <exception cref="FileAlreadyExistsException"></exception>
        /// <exception cref="InsufficientSpaceException"></exception>
        /// <exception cref="MaximumFileCountReachedException"></exception>
        /// <exception cref="TaskCancelledException"></exception>
        internal FileInfo CopyFile(string fullPathForFileToBeCopied, string newPathThatWillPointToTheCopyOfFile, IFileSystemCancellableTaskToken taskToken)
        {
            if (taskToken == null)
            {
                throw new ArgumentNullException("taskToken");
            }
            MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(fullPathForFileToBeCopied, "fullPathForFileToBeCopied");
            MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(newPathThatWillPointToTheCopyOfFile, "newPathThatWillPointToTheCopyOfFile");

            if (_namesComparer.Equals(fullPathForFileToBeCopied, newPathThatWillPointToTheCopyOfFile))
            {
                return
                    (new FileInfo(_nodeResolver.ResolveFileNodeByPath(newPathThatWillPointToTheCopyOfFile).ResolvedNode, newPathThatWillPointToTheCopyOfFile));
            }

            lock (_operationExecutionCriticalSection)
            {
                ThrowIfDisposed(); // так себе проверка на этот раз.
            }

            // Note: не смотрю, хватит ли там места. Хотя отрицательный ответ на такой вопрос мог бы стать поводом, чтобы ничего не копировать.
            try
            {
                CopyFileContents(taskToken, fullPathForFileToBeCopied, newPathThatWillPointToTheCopyOfFile);

                return
                    (new FileInfo(_nodeResolver.ResolveFileNodeByPath(newPathThatWillPointToTheCopyOfFile).ResolvedNode, newPathThatWillPointToTheCopyOfFile));
            }
            catch (Exception)
            {
                try
                {
                    this.DeleteFile(newPathThatWillPointToTheCopyOfFile);
                }
                catch (InvalidPathException)
                {
                }
                catch (ObjectDisposedException)
                {
                    throw new ObjectDisposedException("Работа с файловой системой была вами завершена принудительным вызовом метода Dispose() - до того, как был докопирован файл. Рекомендуется удалить следующий файл при очередном запуске системы (простите - в текущей версии ничего более удобного не сделано): \"{0}\"".FormatWith(newPathThatWillPointToTheCopyOfFile));
                }
                catch (FileNotFoundException)
                {
                }

                throw;
            }
        }
Example #5
0
        /// <exception cref="InvalidPathException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FolderNotFoundException"></exception>
        /// <exception cref="InsufficientSpaceException"></exception>
        /// <exception cref="MaximumFolderCountReachedException"></exception>
        /// <exception cref="ObjectDisposedException"></exception>
        internal ReadOnlyCollection <FileSystemTaskResult> CopyFolder(string fullPathForFolderToCopy, string destinationPathForFolderAndItsContents, IFileSystemCancellableTaskToken taskToken)
        {
            if (taskToken == null)
            {
                throw new ArgumentNullException("taskToken");
            }
            MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(fullPathForFolderToCopy, "fullPathForFolderToCopy");
            MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(destinationPathForFolderAndItsContents, "destinationPathForFolderAndItsContents");

            // TODO: выделить общее у копированиея папок и импорта - там много.

            var allFilesToBeCopied = new List <FileInfo>();

            CreateFoldersNeededToCopy(fullPathForFolderToCopy, destinationPathForFolderAndItsContents, allFilesToBeCopied);

            var copyTaskResults = new List <FileSystemTaskResult>();
            int filesCopied     = 0;
            int percentage      = 0;

            foreach (FileInfo fileInfo in allFilesToBeCopied)
            {
                try
                {
                    if (taskToken.HasBeenCancelled)
                    {
                        copyTaskResults.Add(new FileTaskResult(fileInfo.ToFileAddressable(), null, "Задача снята."));
                    }
                    else
                    {
                        string relativePathToFile = _pathBuilder.GetRelativePath(fullPathForFolderToCopy, fileInfo.FullPath);
                        string destinationPath    = this.PathBuilder.CombinePaths(destinationPathForFolderAndItsContents, relativePathToFile);

                        var tokenWrapper   = new TaskTokenPartialWrapper(taskToken);
                        var copiedFileInfo = this.CopyFile(fileInfo.FullPath, destinationPath, tokenWrapper);
                        copyTaskResults.Add(new FileTaskResult(fileInfo.ToFileAddressable(), copiedFileInfo.ToFileAddressable(), String.Empty));
                    }
                }
                catch (TaskCancelledException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (FileNotFoundException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (FileLockedException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (ObjectDisposedException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (InvalidPathException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (FolderNotFoundException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (FileAlreadyExistsException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (InsufficientSpaceException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                catch (MaximumFileCountReachedException exception)
                {
                    copyTaskResults.Add(CreateCopyTaskFailureFromException(fileInfo, exception));
                }
                finally
                {
                    // Note: дурацкая часть по высчету прогресса везде общая. Надо выносить.

                    filesCopied++;

                    int newPercentage = (filesCopied * 100) / allFilesToBeCopied.Count;

                    if (newPercentage != percentage)
                    {
                        percentage = newPercentage;
                        taskToken.ReportProgressChange(newPercentage);
                    }
                }
            }

            return(copyTaskResults.AsReadOnly());
        }
Example #6
0
 public TaskTokenPartialWrapper(IFileSystemCancellableTaskToken token)
 {
     _token = token;
 }