Exemplo n.º 1
0
        private long GetSize(DirectoryInfo source)
        {
            var sourceInfos            = source.GetFileSystemInfos();
            var fileSystemInfoComparer = new FileSystemInfoComparer();
            var sourceFiles            = sourceInfos.Distinct(fileSystemInfoComparer)
                                         .GroupBy(f => f.FullName, StringComparer.InvariantCultureIgnoreCase)
                                         .Select(f => f.First()).OfType <FileInfo>();
            var sourceDirs = sourceInfos.Distinct(fileSystemInfoComparer)
                             .GroupBy(f => f.FullName, StringComparer.InvariantCultureIgnoreCase)
                             .Select(f => f.First()).OfType <DirectoryInfo>().ToArray();
            long size = 0;

            foreach (var file in sourceFiles)
            {
                if (_cancelRequested)
                {
                    return(size);
                }

                size += file.Length;
            }

            foreach (var sourceDir in sourceDirs)
            {
                if (_cancelRequested)
                {
                    return(size);
                }

                size += GetSize(sourceDir);
            }

            return(size);
        }
Exemplo n.º 2
0
        private void CopyDirectory(DirectoryInfo source, DirectoryInfo target, out bool cancelled)
        {
            if (_cancelRequested)
            {
                cancelled = true;
                return;
            }
            var fileSystemInfoComparer = new FileSystemInfoComparer();

            var sourceFiles = source.GetFileSystemInfos().Distinct(fileSystemInfoComparer).GroupBy(f => f.Name, StringComparer.InvariantCultureIgnoreCase).Select(f => new { f.Key, Files = f.ToArray() })
                              .OrderByDescending(s => s.Files.Length).ThenBy(s => s.Files.First() is DirectoryInfo ? 0 : 1).ToArray();

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

            foreach (var sf in sourceFiles)
            {
                if (sf.Files.Length > 1)
                {
                    Console.WriteLine("Duplicate file name: {0}: ", string.Join(", ", sf.Files.Select(s => s.FullName)));
                }
                var sourceFile = sf.Files.First();
                if (_cancelRequested)
                {
                    cancelled = true;
                    return;
                }

                var  directory = sourceFile as DirectoryInfo;
                var  file      = sourceFile as FileInfo;
                bool wasCancelled;
                if (directory != null)
                {
                    CopyDirectory(directory, new DirectoryInfo(Path.Combine(target.FullName, directory.Name)), out wasCancelled);
                }

                if (file == null)
                {
                    continue;
                }

                var outputFile = Path.Combine(target.FullName, file.Name);
                CopyIncrementally(file, outputFile, bytesRead =>
                {
                    _totalBytesCopied += bytesRead;
                    var runningTime    = _startTime.HasValue ? (DateTime.UtcNow - _startTime.Value) : default(TimeSpan?);
                    lock (this)
                    {
                        Console.SetCursorPosition(0, Console.CursorTop);

                        var total = _totalSize.HasValue && !string.IsNullOrWhiteSpace(_totalSizeString)
                                                                        ? string.Format("{0}/{1} ({2}%)", HumanReadableSize(_totalBytesCopied), _totalSizeString,
                                                                                        (_totalBytesCopied * 100) / _totalSize.Value)
                                                                        : HumanReadableSize(_totalBytesCopied);

                        var message = runningTime.HasValue
                                                                          ? string.Format("{0} copied ({1}/sec.)", total,
                                                                                          HumanReadableSize(_totalBytesCopied / runningTime.Value.TotalSeconds))
                                                                          : string.Format("{0} copied.", total);

                        if (message.Length > Console.WindowWidth - 1)
                        {
                            message = message.Substring(Console.WindowWidth - 1);
                        }
                        var newMessageLength = message.Length;
                        var blanksNeeded     = Console.WindowWidth - newMessageLength - 1;
                        var chars            = new string(new char[blanksNeeded].Select(c => ' ').ToArray());
                        message = string.Format("{0}{1}", message, chars);

                        Console.Write(message);
                    }
                    return(_cancelRequested);
                });
            }
            cancelled = false;
        }