MeasureTime() 공개 정적인 메소드

public static MeasureTime ( string operationTitle ) : IDisposable
operationTitle string
리턴 IDisposable
예제 #1
0
 public static HashSet <string> GetRelativePathsOfAllFiles(string rootFolder)
 {
     using (Log.MeasureTime("Scanning files in " + rootFolder))
     {
         var files = Directory.GetFiles(rootFolder, "*", SearchOption.AllDirectories);
         return(GetRelativePaths(rootFolder, files));
     }
 }
예제 #2
0
        private static void Main(string[] args)
        {
            string source      = null;
            string destination = null;

            if (args.Length == 2)
            {
                source      = args[0];
                destination = args[1];
            }
            else
            {
                PrintUsage();
                return;
            }

            if (Directory.Exists(source))
            {
                source = Path.GetFullPath(source);
                if (Directory.Exists(destination))
                {
                    destination = Path.GetFullPath(destination);
                }

                using (Log.MeasureTime("Total time"))
                {
                    Sync.Directories(source, destination);
                }

                Log.PrintFinalReport();

                return;
            }

            if (File.Exists(source) && Directory.Exists(destination))
            {
                Sync.Files(source, Path.Combine(destination, Path.GetFileName(source)));
                return;
            }

            if (File.Exists(source))
            {
                Sync.Files(source, destination);
                return;
            }

            Console.Error.WriteLine($"Cannot sync {source} to {destination}");
        }
예제 #3
0
        /// <summary>
        /// Assumes leftRoot is an existing folder. rightRoot may not exist if operating in speculative mode.
        /// </summary>
        public static FolderDiffResults DiffFolders(
            string leftRoot,
            string rightRoot,
            string pattern,
            bool recursive       = true,
            bool compareContents = true)
        {
            HashSet <string> leftRelativePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            HashSet <string> leftOnlyFolders   = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            using (Log.MeasureTime("Scanning source directory"))
            {
                GetRelativePathsOfAllFiles(leftRoot, pattern, recursive, leftRelativePaths, leftOnlyFolders);
            }

            HashSet <string> rightRelativePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            HashSet <string> rightOnlyFolders   = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (Directory.Exists(rightRoot))
            {
                using (Log.MeasureTime("Scanning destination directory"))
                {
                    GetRelativePathsOfAllFiles(rightRoot, pattern, recursive, rightRelativePaths, rightOnlyFolders);
                }
            }

            var leftOnlyFiles  = new List <string>();
            var identicalFiles = new List <string>();
            var changedFiles   = new List <string>();
            var rightOnlyFiles = new HashSet <string>(rightRelativePaths, StringComparer.OrdinalIgnoreCase);

            var commonFolders = leftOnlyFolders.Intersect(rightOnlyFolders, StringComparer.OrdinalIgnoreCase).ToArray();

            leftOnlyFolders.ExceptWith(commonFolders);
            rightOnlyFolders.ExceptWith(commonFolders);

            int current = 0;
            int total   = leftRelativePaths.Count;

            using (Log.MeasureTime("Comparing"))
            {
                Parallel.ForEach(
                    leftRelativePaths,
                    new ParallelOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount * 2
                },
                    left =>
                {
                    var leftFullPath  = leftRoot + left;
                    var rightFullPath = rightRoot + left;

                    bool rightContains = rightRelativePaths.Contains(left);
                    if (rightContains)
                    {
                        bool areSame;
                        try
                        {
                            areSame = !compareContents || Files.AreContentsIdentical(leftFullPath, rightFullPath);
                        }
                        catch (Exception ex)
                        {
                            Log.WriteError(ex.ToString());
                            return;
                        }

                        if (areSame)
                        {
                            lock (identicalFiles)
                            {
                                identicalFiles.Add(left);
                            }
                        }
                        else
                        {
                            lock (changedFiles)
                            {
                                changedFiles.Add(left);
                            }
                        }
                    }
                    else
                    {
                        lock (leftOnlyFiles)
                        {
                            leftOnlyFiles.Add(left);
                        }
                    }

                    lock (rightOnlyFiles)
                    {
                        rightOnlyFiles.Remove(left);
                    }

                    Interlocked.Increment(ref current);
                });
            }

            using (Log.MeasureTime("Sorting"))
            {
                leftOnlyFiles.Sort();
                identicalFiles.Sort();
                changedFiles.Sort();

                return(new FolderDiffResults(
                           leftOnlyFiles,
                           identicalFiles,
                           changedFiles,
                           rightOnlyFiles.OrderBy(s => s).ToArray(),
                           leftOnlyFolders.OrderBy(s => s).ToArray(),
                           rightOnlyFolders.OrderBy(s => s).ToArray()));
            }
        }
예제 #4
0
        /// <summary>
        /// Assumes leftRoot is an existing folder. rightRoot may not exist if operating in speculative mode.
        /// </summary>
        public static FolderDiffResults DiffFolders(
            string leftRoot,
            string rightRoot,
            Log log,
            CancellationToken token,
            bool compareContents = true,
            bool respectDate     = true)
        {
            var leftRelativePaths = new ConcurrentBag <string>();

            using (log.MeasureTime("Scanning source directory"))
            {
                GetRelativePathsOfAllFiles(leftRoot, leftRelativePaths, token);
            }

            var rightRelativePaths = new ConcurrentBag <string>();

            if (Directory.Exists(rightRoot))
            {
                using (log.MeasureTime("Scanning destination directory"))
                {
                    GetRelativePathsOfAllFiles(rightRoot, rightRelativePaths, token);
                }
            }

            var leftOnlyFiles  = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var identicalFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var changedFiles   = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var rightOnlyFiles = new HashSet <string>(rightRelativePaths, StringComparer.OrdinalIgnoreCase);

            using (log.MeasureTime("Comparing"))
            {
                leftRelativePaths
                .Distinct(StringComparer.OrdinalIgnoreCase)
                .ForEach(AnalyzeFile);
            }

            using (log.MeasureTime("Sorting"))
            {
                var leftOnlyFilesList = leftOnlyFiles.ToList();
                leftOnlyFilesList.Sort();

                var identicalFilesList = identicalFiles.ToList();
                identicalFilesList.Sort();

                var changedFilesList = changedFiles.ToList();
                changedFilesList.Sort();

                return(new FolderDiffResults(
                           leftOnlyFilesList,
                           identicalFilesList,
                           changedFilesList,
                           rightOnlyFiles.OrderBy(s => s).ToArray()));
            }

            void AnalyzeFile(string path)
            {
                var leftFullPath  = leftRoot + path;
                var rightFullPath = rightRoot + path;

                var rightContains = rightRelativePaths.Contains(path);

                if (rightContains)
                {
                    var areSame = true;
                    try
                    {
                        areSame = !compareContents ||
                                  Files.AreContentsIdentical(leftFullPath, rightFullPath, token) ||
                                  respectDate
                            ? File.GetLastWriteTimeUtc(leftFullPath) <= File.GetLastWriteTimeUtc(rightFullPath)
                            : true;
                    }
                    catch (Exception ex)
                    {
                        log.WriteError(ex.ToString());
                        return;
                    }

                    if (areSame)
                    {
                        identicalFiles.Add(path);
                    }
                    else
                    {
                        changedFiles.Add(path);
                    }
                }
                else
                {
                    leftOnlyFiles.Add(path);
                }

                rightOnlyFiles.Remove(path);
            }
        }
예제 #5
0
        private static int Main(string[] args)
        {
            try
            {
                var arguments = new Arguments(args);
                if (arguments.Help || args.Length == 0)
                {
                    PrintUsage();
                    return(0);
                }

                if (!string.IsNullOrEmpty(arguments.Error))
                {
                    Log.WriteError("Invalid arguments:" + Environment.NewLine + arguments.Error + Environment.NewLine);
                    PrintUsage();
                    return(1);
                }

                string source      = arguments.Source;
                string destination = arguments.Destination;

                if (Directory.Exists(source))
                {
                    source = Path.GetFullPath(source);
                    if (Directory.Exists(destination))
                    {
                        destination = Path.GetFullPath(destination);
                    }

                    using (Log.MeasureTime("Total time"))
                    {
                        Sync.Directories(source, destination, arguments);
                    }

                    Log.PrintFinalReport();

                    return(0);
                }

                if (File.Exists(source))
                {
                    source = Path.GetFullPath(source);

                    if (Directory.Exists(destination))
                    {
                        destination = Path.GetFullPath(destination);
                        destination = Path.Combine(destination, Path.GetFileName(source));
                    }

                    if (File.Exists(destination))
                    {
                        destination = Path.GetFullPath(destination);
                    }

                    if (arguments.Pattern != "*")
                    {
                        Log.WriteError($"The pattern cannot be specified when processing a single file.");
                        return(4);
                    }

                    Sync.Files(source, destination, arguments);
                    return(0);
                }

                Log.WriteError($"Cannot find file or directory: {source}");
                return(2);
            }
            catch (Exception ex)
            {
                Log.WriteError($"Unrecoverable error: {ex.Message}");
                return(3);
            }
        }
예제 #6
0
        /// <summary>
        /// Assumes source directory exists. destination may or may not exist.
        /// </summary>
        public static void Directories(string source, string destination, Arguments arguments)
        {
            if (!Directory.Exists(destination))
            {
                FileSystem.CreateDirectory(destination, arguments.WhatIf);
            }

            source = Paths.TrimSeparator(source);
            destination = Paths.TrimSeparator(destination);

            var diff = Folders.DiffFolders(
                source,
                destination,
                arguments.Pattern,
                recursive: !arguments.Nonrecursive,
                compareContents:
                    arguments.UpdateChangedFiles ||
                    arguments.DeleteChangedFiles ||
                    arguments.DeleteSameFiles);

            bool changesMade = false;
            int filesFailedToCopy = 0;
            int filesFailedToDelete = 0;
            int foldersFailedToCreate = 0;
            int foldersFailedToDelete = 0;

            if (arguments.CopyLeftOnlyFiles)
            {
                using (Log.MeasureTime("Copying new files"))
                {
                    foreach (var leftOnly in diff.LeftOnlyFiles)
                    {
                        var destinationFilePath = destination + leftOnly;
                        if (!FileSystem.CopyFile(source + leftOnly, destinationFilePath, arguments.WhatIf))
                        {
                            filesFailedToCopy++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.UpdateChangedFiles)
            {
                using (Log.MeasureTime("Updating changed files"))
                {
                    foreach (var changed in diff.ChangedFiles)
                    {
                        var destinationFilePath = destination + changed;
                        if (!FileSystem.CopyFile(source + changed, destinationFilePath, arguments.WhatIf))
                        {
                            filesFailedToCopy++;
                        }

                        changesMade = true;
                    }
                }
            }
            else if (arguments.DeleteChangedFiles)
            {
                using (Log.MeasureTime("Deleting changed files"))
                {
                    foreach (var changed in diff.ChangedFiles)
                    {
                        var destinationFilePath = destination + changed;
                        if (!FileSystem.DeleteFile(destinationFilePath, arguments.WhatIf))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.DeleteSameFiles)
            {
                using (Log.MeasureTime("Deleting identical files"))
                {
                    foreach (var same in diff.IdenticalFiles)
                    {
                        var destinationFilePath = destination + same;
                        if (!FileSystem.DeleteFile(destinationFilePath, arguments.WhatIf))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.DeleteRightOnlyFiles)
            {
                using (Log.MeasureTime("Deleting extra files"))
                {
                    foreach (var rightOnly in diff.RightOnlyFiles)
                    {
                        var deletedFilePath = destination + rightOnly;
                        if (!FileSystem.DeleteFile(deletedFilePath, arguments.WhatIf))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            int foldersCreated = 0;
            if (arguments.CopyEmptyDirectories)
            {
                using (Log.MeasureTime("Creating folders"))
                {
                    foreach (var leftOnlyFolder in diff.LeftOnlyFolders)
                    {
                        var newFolder = destination + leftOnlyFolder;
                        if (!Directory.Exists(newFolder))
                        {
                            if (!FileSystem.CreateDirectory(newFolder, arguments.WhatIf))
                            {
                                foldersFailedToCreate++;
                            }
                            else
                            {
                                foldersCreated++;
                            }

                            changesMade = true;
                        }
                    }
                }
            }

            int foldersDeleted = 0;
            if (arguments.DeleteRightOnlyDirectories)
            {
                using (Log.MeasureTime("Deleting folders"))
                {
                    foreach (var rightOnlyFolder in diff.RightOnlyFolders)
                    {
                        var deletedFolderPath = destination + rightOnlyFolder;
                        if (Directory.Exists(deletedFolderPath))
                        {
                            if (!FileSystem.DeleteDirectory(deletedFolderPath, arguments.WhatIf))
                            {
                                foldersFailedToDelete++;
                            }
                            else
                            {
                                foldersDeleted++;
                            }

                            changesMade = true;
                        }
                    }
                }
            }

            if (diff.LeftOnlyFiles.Any() && arguments.CopyLeftOnlyFiles)
            {
                var count = diff.LeftOnlyFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have copied {count} new {fileOrFiles}", ConsoleColor.Green);
                }
                else
                {
                    Log.WriteLine($"{count} new {fileOrFiles} copied", ConsoleColor.Green);
                }
            }

            if (foldersCreated > 0 && arguments.CopyEmptyDirectories)
            {
                var folderOrFolders = Pluralize("folder", foldersCreated);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have created {foldersCreated} {folderOrFolders}", ConsoleColor.Green);
                }
                else
                {
                    Log.WriteLine($"{foldersCreated} {folderOrFolders} created", ConsoleColor.Green);
                }
            }

            if (diff.ChangedFiles.Any() && arguments.UpdateChangedFiles)
            {
                var count = diff.ChangedFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have updated {count} changed {fileOrFiles}", ConsoleColor.Yellow);
                }
                else
                {
                    Log.WriteLine($"{count} changed {fileOrFiles} updated", ConsoleColor.Yellow);
                }
            }

            if (diff.ChangedFiles.Any() && arguments.DeleteChangedFiles)
            {
                var count = diff.ChangedFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have deleted {count} changed {fileOrFiles}", ConsoleColor.Yellow);
                }
                else
                {
                    Log.WriteLine($"{count} changed {fileOrFiles} deleted", ConsoleColor.Yellow);
                }
            }

            if (diff.RightOnlyFiles.Any() && arguments.DeleteRightOnlyFiles)
            {
                var count = diff.RightOnlyFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have deleted {count} right-only {fileOrFiles}", ConsoleColor.Red);
                }
                else
                {
                    Log.WriteLine($"{count} right-only {fileOrFiles} deleted", ConsoleColor.Red);
                }
            }

            if (foldersDeleted > 0 && arguments.DeleteRightOnlyDirectories)
            {
                var folderOrFolders = Pluralize("folder", foldersDeleted);
                if (arguments.WhatIf)
                {
                    Log.WriteLine($"Would have deleted {foldersDeleted} right-only {folderOrFolders}", ConsoleColor.Red);
                }
                else
                {
                    Log.WriteLine($"{foldersDeleted} right-only {folderOrFolders} deleted", ConsoleColor.Red);
                }
            }

            if (diff.IdenticalFiles.Any())
            {
                var count = diff.IdenticalFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.DeleteSameFiles)
                {
                    if (arguments.WhatIf)
                    {
                        Log.WriteLine($"Would have deleted {count} identical {fileOrFiles} from destination", ConsoleColor.White);
                    }
                    else
                    {
                        Log.WriteLine($"{count} identical {fileOrFiles} deleted from destination", ConsoleColor.White);
                    }
                }
                else
                {
                    Log.WriteLine($"{count} identical {fileOrFiles}", ConsoleColor.White);
                }
            }

            if (filesFailedToCopy > 0)
            {
                Log.WriteLine($"Failed to copy {filesFailedToCopy} {Pluralize("file", filesFailedToCopy)}", ConsoleColor.Red);
            }

            if (filesFailedToDelete > 0)
            {
                Log.WriteLine($"Failed to delete {filesFailedToDelete} {Pluralize("file", filesFailedToDelete)}.", ConsoleColor.Red);
            }

            if (foldersFailedToCreate > 0)
            {
                Log.WriteLine($"Failed to create {foldersFailedToCreate} {Pluralize("folder", foldersFailedToCreate)}.", ConsoleColor.Red);
            }

            if (foldersFailedToDelete > 0)
            {
                Log.WriteLine($"Failed to delete {foldersFailedToDelete} {Pluralize("folder", foldersFailedToDelete)}.", ConsoleColor.Red);
            }

            if (!changesMade)
            {
                if (arguments.WhatIf)
                {
                    Log.WriteLine("Would have made no changes.", ConsoleColor.White);
                }
                else
                {
                    Log.WriteLine("Made no changes.", ConsoleColor.White);
                }
            }

            // if there were no errors, delete the cache of the folder contents. Otherwise
            // chances are they're going to restart the process, so we might needs the cache
            // next time.
            if (filesFailedToCopy == 0 &&
                filesFailedToDelete == 0 &&
                foldersFailedToCreate == 0 &&
                foldersFailedToDelete == 0)
            {
                DirectoryContentsCache.ClearWrittenFilesFromCache();
            }
        }
예제 #7
0
        /// <summary>
        /// Assumes source directory exists. destination may or may not exist.
        /// </summary>
        public static void Directories(string source, string destination)
        {
            if (!Directory.Exists(destination))
            {
                Directory.CreateDirectory(destination);
            }

            source      = Paths.TrimSeparator(source);
            destination = Paths.TrimSeparator(destination);

            var diff = Folders.DiffFolders(source, destination);

            using (Log.MeasureTime("Copying new files"))
            {
                foreach (var leftOnly in diff.LeftOnlyFiles)
                {
                    var destinationFilePath = destination + leftOnly;
                    var destinationFolder   = Path.GetDirectoryName(destinationFilePath);
                    Directory.CreateDirectory(destinationFolder);
                    File.Copy(source + leftOnly, destinationFilePath);
                    Console.WriteLine("Copy " + destinationFilePath);
                }
            }

            using (Log.MeasureTime("Overwriting changed files"))
            {
                foreach (var changed in diff.ChangedFiles)
                {
                    var destinationFilePath = destination + changed;
                    File.Copy(source + changed, destinationFilePath, overwrite: true);
                    Console.WriteLine("Overwrite " + destinationFilePath);
                }
            }

            using (Log.MeasureTime("Deleting extra files"))
            {
                foreach (var rightOnly in diff.RightOnlyFiles)
                {
                    var deletedFilePath = destination + rightOnly;
                    var attributes      = File.GetAttributes(deletedFilePath);
                    if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                    {
                        File.SetAttributes(deletedFilePath, attributes & ~FileAttributes.ReadOnly);
                    }

                    File.Delete(deletedFilePath);
                    Console.WriteLine("Delete " + deletedFilePath);
                }
            }

            int foldersCreated = 0;

            using (Log.MeasureTime("Creating folders"))
            {
                foreach (var leftOnlyFolder in diff.LeftOnlyFolders)
                {
                    var newFolder = destination + leftOnlyFolder;
                    if (!Directory.Exists(newFolder))
                    {
                        Directory.CreateDirectory(newFolder);
                        Console.WriteLine("Create " + newFolder);
                        foldersCreated++;
                    }
                }
            }

            int foldersDeleted = 0;

            using (Log.MeasureTime("Deleting folders"))
            {
                foreach (var rightOnlyFolder in diff.RightOnlyFolders)
                {
                    var deletedFolderPath = destination + rightOnlyFolder;
                    if (Directory.Exists(deletedFolderPath))
                    {
                        Directory.Delete(deletedFolderPath, recursive: true);
                        Console.WriteLine("Delete " + deletedFolderPath);
                        foldersDeleted++;
                    }
                }
            }

            if (diff.LeftOnlyFiles.Any())
            {
                Log.WriteLine($"{diff.LeftOnlyFiles.Count()} new files", ConsoleColor.Green);
            }

            if (foldersCreated > 0)
            {
                Log.WriteLine($"{foldersCreated} folders created", ConsoleColor.Green);
            }

            if (diff.ChangedFiles.Any())
            {
                Log.WriteLine($"{diff.ChangedFiles.Count()} changed files", ConsoleColor.Yellow);
            }

            if (diff.RightOnlyFiles.Any())
            {
                Log.WriteLine($"{diff.RightOnlyFiles.Count()} deleted files", ConsoleColor.Red);
            }

            if (foldersDeleted > 0)
            {
                Log.WriteLine($"{foldersDeleted} folders deleted", ConsoleColor.Red);
            }

            if (diff.IdenticalFiles.Any())
            {
                Log.WriteLine($"{diff.IdenticalFiles.Count()} identical files", ConsoleColor.White);
            }
        }
예제 #8
0
        /// <summary>
        /// Assumes both leftRoot and rightRoot are existing folders.
        /// </summary>
        public static FolderDiffResults DiffFolders(string leftRoot, string rightRoot)
        {
            var leftRelativePaths  = GetRelativePathsOfAllFiles(leftRoot);
            var leftOnlyFolders    = GetRelativePathsOfAllFolders(leftRoot);
            var rightRelativePaths = GetRelativePathsOfAllFiles(rightRoot);
            var rightOnlyFolders   = GetRelativePathsOfAllFolders(rightRoot);

            var leftOnlyFiles  = new List <string>();
            var identicalFiles = new List <string>();
            var changedFiles   = new List <string>();
            var rightOnlyFiles = new HashSet <string>(rightRelativePaths, StringComparer.OrdinalIgnoreCase);

            var commonFolders = leftOnlyFolders.Intersect(rightOnlyFolders, StringComparer.OrdinalIgnoreCase).ToArray();

            leftOnlyFolders.ExceptWith(commonFolders);
            rightOnlyFolders.ExceptWith(commonFolders);

            int current = 0;
            int total   = leftRelativePaths.Count;

            using (Log.MeasureTime("Comparing"))
            {
                Parallel.ForEach(
                    leftRelativePaths,
                    new ParallelOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount * 2
                },
                    left =>
                {
                    var leftFullPath  = leftRoot + left;
                    var rightFullPath = rightRoot + left;

                    bool rightContains = rightRelativePaths.Contains(left);
                    if (rightContains)
                    {
                        bool areSame = Files.AreContentsIdentical(leftFullPath, rightFullPath);
                        if (areSame)
                        {
                            lock (identicalFiles)
                            {
                                identicalFiles.Add(left);
                            }
                        }
                        else
                        {
                            lock (changedFiles)
                            {
                                changedFiles.Add(left);
                            }
                        }
                    }
                    else
                    {
                        lock (leftOnlyFiles)
                        {
                            leftOnlyFiles.Add(left);
                        }
                    }

                    lock (rightOnlyFiles)
                    {
                        rightOnlyFiles.Remove(left);
                    }

                    Interlocked.Increment(ref current);
                });
            }

            using (Log.MeasureTime("Sorting"))
            {
                leftOnlyFiles.Sort();
                identicalFiles.Sort();
                changedFiles.Sort();

                return(new FolderDiffResults(
                           leftOnlyFiles,
                           identicalFiles,
                           changedFiles,
                           rightOnlyFiles.OrderBy(s => s).ToArray(),
                           leftOnlyFolders.OrderBy(s => s).ToArray(),
                           rightOnlyFolders.OrderBy(s => s).ToArray()));
            }
        }
예제 #9
0
        /// <summary>
        /// Assumes source directory exists. destination may or may not exist.
        /// </summary>
        public static void Directories(string source, string destination, Log log, CancellationToken token, Arguments arguments)
        {
            if (!Directory.Exists(destination))
            {
                FileSystem.CreateDirectory(destination, log);
            }

            source      = Paths.TrimSeparator(source);
            destination = Paths.TrimSeparator(destination);

            var diff = Folders.DiffFolders(
                source,
                destination,
                log,
                token,
                compareContents:
                arguments.UpdateChangedFiles ||
                arguments.DeleteChangedFiles ||
                arguments.DeleteSameFiles,
                arguments.RespectLastAccessDateTime);

            bool changesMade         = false;
            int  filesFailedToCopy   = 0;
            int  filesFailedToDelete = 0;

            if (arguments.CopyLeftOnlyFiles)
            {
                using (log.MeasureTime("Copying new files"))
                {
                    foreach (var leftOnly in diff.LeftOnlyFiles)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        var destinationFilePath = destination + leftOnly;
                        if (!FileSystem.CopyFile(source + leftOnly, destinationFilePath, log))
                        {
                            filesFailedToCopy++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.UpdateChangedFiles)
            {
                using (log.MeasureTime("Updating changed files"))
                {
                    foreach (var changed in diff.ChangedFiles)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        var destinationFilePath = destination + changed;
                        if (!FileSystem.CopyFile(source + changed, destinationFilePath, log))
                        {
                            filesFailedToCopy++;
                        }

                        changesMade = true;
                    }
                }
            }
            else if (arguments.DeleteChangedFiles)
            {
                using (log.MeasureTime("Deleting changed files"))
                {
                    foreach (var changed in diff.ChangedFiles)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        var destinationFilePath = destination + changed;
                        if (!FileSystem.DeleteFile(destinationFilePath, log))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.DeleteSameFiles)
            {
                using (log.MeasureTime("Deleting identical files"))
                {
                    foreach (var same in diff.IdenticalFiles)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        var destinationFilePath = destination + same;
                        if (!FileSystem.DeleteFile(destinationFilePath, log))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (arguments.DeleteRightOnlyFiles)
            {
                using (log.MeasureTime("Deleting extra files"))
                {
                    foreach (var rightOnly in diff.RightOnlyFiles)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        var deletedFilePath = destination + rightOnly;
                        if (!FileSystem.DeleteFile(deletedFilePath, log))
                        {
                            filesFailedToDelete++;
                        }

                        changesMade = true;
                    }
                }
            }

            if (diff.LeftOnlyFiles.Any() && arguments.CopyLeftOnlyFiles)
            {
                var count       = diff.LeftOnlyFiles.Count();
                var fileOrFiles = Pluralize("file", count);

                log.WriteLine($"{count} new {fileOrFiles} copied", ConsoleColor.Green);
            }

            if (diff.ChangedFiles.Any() && arguments.UpdateChangedFiles)
            {
                var count       = diff.ChangedFiles.Count();
                var fileOrFiles = Pluralize("file", count);

                log.WriteLine($"{count} changed {fileOrFiles} updated", ConsoleColor.Yellow);
            }

            if (diff.ChangedFiles.Any() && arguments.DeleteChangedFiles)
            {
                var count       = diff.ChangedFiles.Count();
                var fileOrFiles = Pluralize("file", count);

                log.WriteLine($"{count} changed {fileOrFiles} deleted", ConsoleColor.Yellow);
            }

            if (diff.RightOnlyFiles.Any() && arguments.DeleteRightOnlyFiles)
            {
                var count       = diff.RightOnlyFiles.Count();
                var fileOrFiles = Pluralize("file", count);

                log.WriteLine($"{count} right-only {fileOrFiles} deleted", ConsoleColor.Red);
            }

            if (diff.IdenticalFiles.Any())
            {
                var count       = diff.IdenticalFiles.Count();
                var fileOrFiles = Pluralize("file", count);
                if (arguments.DeleteSameFiles)
                {
                    log.WriteLine($"{count} identical {fileOrFiles} deleted from destination", ConsoleColor.White);
                }
                else
                {
                    log.WriteLine($"{count} identical {fileOrFiles}", ConsoleColor.White);
                }
            }

            if (filesFailedToCopy > 0)
            {
                log.WriteLine($"Failed to copy {filesFailedToCopy} {Pluralize("file", filesFailedToCopy)}", ConsoleColor.Red);
            }

            if (filesFailedToDelete > 0)
            {
                log.WriteLine($"Failed to delete {filesFailedToDelete} {Pluralize("file", filesFailedToDelete)}.", ConsoleColor.Red);
            }

            if (!changesMade)
            {
                log.WriteLine("Made no changes.", ConsoleColor.White);
            }

            log.PrintFinalReport();
        }