예제 #1
0
        /// <summary>
        /// Moves a file info to a new location, allowing specification of behaviour
        /// </summary>
        /// <param name="file">The file to move</param>
        /// <param name="newPath">The target path for the file</param>
        /// <param name="behaviour">How conflicting files should be handled</param>
        /// <returns>An object containing information relevant to the operation</returns>
        public static FileMoveResult MoveTo(this FileInfo file, string newPath, ExistingFileBehaviour behaviour)
        {
            if (file is null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (newPath is null)
            {
                throw new ArgumentNullException(nameof(newPath));
            }

            if (!File.Exists(newPath))
            {
                file.MoveTo(newPath);

                return(new FileMoveResult()
                {
                    FileInfo = new FileInfo(newPath),
                    Result = FileMoveResultKind.Moved
                });
            }
            else
            {
                switch (behaviour)
                {
                case ExistingFileBehaviour.Error:
                    throw new FileAlreadyExistsException();

                case ExistingFileBehaviour.Overwrite:
                    File.Delete(newPath);
                    file.MoveTo(newPath);
                    return(new FileMoveResult()
                    {
                        FileInfo = new FileInfo(newPath),
                        Result = FileMoveResultKind.Overwritten
                    });

                case ExistingFileBehaviour.Rename:
                    newPath = IOHelper.FindFileName(newPath);
                    file.MoveTo(newPath);
                    return(new FileMoveResult()
                    {
                        FileInfo = new FileInfo(newPath),
                        Result = FileMoveResultKind.Renamed
                    });

                case ExistingFileBehaviour.Skip:
                    return(new FileMoveResult()
                    {
                        FileInfo = new FileInfo(file.FullName),
                        Result = FileMoveResultKind.Skipped
                    });

                default:
                    throw new NotImplementedException();
                }
            }
        }
        public static void Merge(this DirectoryInfo source, string newPath, ExistingFileBehaviour existingFileBehaviour = ExistingFileBehaviour.Error)
        {
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (!Directory.Exists(newPath))
            {
                throw new DirectoryNotFoundException(newPath);
            }

            source.RecursiveMerge(newPath, existingFileBehaviour);
        }
        public static DirectoryMoveResult MoveTo(this DirectoryInfo directory, string newPath, ExistingDirectoryBehaviour existingDirectoryBehaviour, ExistingFileBehaviour existingFileBehaviour = ExistingFileBehaviour.Error)
        {
            if (directory is null)
            {
                throw new ArgumentNullException(nameof(directory));
            }

            if (string.IsNullOrWhiteSpace(newPath))
            {
                throw new ArgumentException($"'{nameof(newPath)}' cannot be null or whitespace.", nameof(newPath));
            }

            DirectoryInfo newDir = new DirectoryInfo(newPath);

            if (!Directory.Exists(newPath))
            {
                if (string.Equals(newDir.Root, directory.Root))
                {
                    directory.MoveTo(newPath);

                    return(new DirectoryMoveResult()
                    {
                        DirectoryInfo = new DirectoryInfo(newPath),
                        Result = DirectoryMoveResultKind.Moved
                    });
                }
                else
                {
                    directory.RecursiveMerge(newPath, existingFileBehaviour);
                    return(new DirectoryMoveResult()
                    {
                        DirectoryInfo = new DirectoryInfo(newPath),
                        Result = DirectoryMoveResultKind.Merged
                    });
                }
            }
            else
            {
                switch (existingDirectoryBehaviour)
                {
                case ExistingDirectoryBehaviour.Error:
                    throw new DirectoryAlreadyExistsException();

                case ExistingDirectoryBehaviour.Merge:
                    directory.RecursiveMerge(newPath, existingFileBehaviour);
                    return(new DirectoryMoveResult()
                    {
                        DirectoryInfo = new DirectoryInfo(newPath),
                        Result = DirectoryMoveResultKind.Merged
                    });

                case ExistingDirectoryBehaviour.Rename:
                    newPath = IOHelper.FindDirectoryName(newPath);
                    directory.MoveTo(newPath);
                    return(new DirectoryMoveResult()
                    {
                        DirectoryInfo = new DirectoryInfo(newPath),
                        Result = DirectoryMoveResultKind.Renamed
                    });

                case ExistingDirectoryBehaviour.Skip:
                    return(new DirectoryMoveResult()
                    {
                        DirectoryInfo = new DirectoryInfo(directory.FullName),
                        Result = DirectoryMoveResultKind.Skipped
                    });

                default:
                    throw new NotImplementedException();
                }
            }
        }
        private static List <FileMoveResult> RecursiveMerge(this DirectoryInfo source, string newpath, ExistingFileBehaviour existingFileBehaviour = ExistingFileBehaviour.Error)
        {
            List <FileMoveInfo> MoveInfo = new List <FileMoveInfo>();

            foreach (FileInfo fi in source.EnumerateFiles("*", SearchOption.AllDirectories))
            {
                MoveInfo.Add(new FileMoveInfo(fi, source.FullName, newpath));
            }

            if (existingFileBehaviour == ExistingFileBehaviour.Error)
            {
                FileMoveInfo firstExists = MoveInfo.FirstOrDefault(f => f.TargetExists);

                if (firstExists != null)
                {
                    throw new FileAlreadyExistsException(firstExists.TargetPath);
                }
            }

            foreach (FileMoveInfo thisMoveInfo in MoveInfo)
            {
                DirectoryInfo parentDirectory = new FileInfo(thisMoveInfo.TargetPath).Directory;

                if (!parentDirectory.Exists)
                {
                    parentDirectory.Create();
                }

                thisMoveInfo.Source.MoveTo(thisMoveInfo.TargetPath, existingFileBehaviour);
            }

            List <DirectoryInfo> toRemove = source.EnumerateDirectories("*", SearchOption.AllDirectories).OrderByDescending(d => d.FullName.Length).ToList();

            foreach (DirectoryInfo di in toRemove)
            {
                if (!di.EnumerateFileSystemInfos().Any())
                {
                    di.Delete();
                }
            }

            if (!source.EnumerateFileSystemInfos().Any())
            {
                source.Delete();
            }

            return(MoveInfo.Select(m => m.Result).ToList());
        }