Created
February 27, 2018 23:59
-
-
Save kenanhancer/33266e42814e156aba6e7b4a2b54c641 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ProgressBar5 | |
{ | |
public class Program | |
{ | |
static int consoleTop = 1; | |
static CancellationTokenSource cts; | |
static string sourcePath = @"C:\"; | |
static string destinationPath = @"C:\TestCopy"; | |
static char[] progressCharacters = @"/-\|".ToArray(); | |
public static void Main(string[] args) | |
{ | |
Console.WindowWidth = Console.LargestWindowWidth / 2; | |
Console.WindowHeight = Console.LargestWindowHeight / 2; | |
MainAsync().Wait(); | |
} | |
static async Task MainAsync() | |
{ | |
cts = new CancellationTokenSource(); | |
Console.CancelKeyPress += (s, e) => | |
{ | |
e.Cancel = true; | |
cts.Cancel(); | |
}; | |
string[] files = Directory.GetFiles(sourcePath); | |
if (Directory.Exists(destinationPath)) | |
Directory.Delete(destinationPath, true); | |
Directory.CreateDirectory(destinationPath); | |
List taskList = new List(); | |
Task copyTask; | |
string msg = $@"Copying files from {sourcePath} directory to {destinationPath} directory."; | |
Console.WriteLine(msg); | |
Console.WriteLine(String.Join("", Enumerable.Repeat("-", msg.Length))); | |
foreach (string sourceFilePath in files) | |
{ | |
copyTask = CopyFileToDirectory(sourceFilePath, destinationPath, cts.Token); | |
taskList.Add(copyTask); | |
} | |
await Task.WhenAll(taskList).ContinueWith((f, state) => | |
{ | |
List tList = (List)state; | |
int successCount = tList.Count(ff => ff.Status == TaskStatus.RanToCompletion); | |
Console.ForegroundColor = ConsoleColor.White; | |
Console.SetCursorPosition(0, ++consoleTop); | |
msg = $"Total file count is {files.Count()}.\nTotal copied file count is {successCount}."; | |
Console.WriteLine(String.Join("", Enumerable.Repeat("-", msg.Length))); | |
if (cts.IsCancellationRequested) | |
{ | |
Console.WriteLine("Application is cancelled."); | |
} | |
Console.WriteLine(msg); | |
}, taskList); | |
Console.ReadLine(); | |
} | |
static async Task CopyFileToDirectory(string sourceFilePath, string destinationDirPath, CancellationToken token) | |
{ | |
FileInfo sourceFi = new FileInfo(sourceFilePath); | |
string message = $"Copying {sourceFi.Name} "; | |
using (FileStream destinationFs = File.OpenWrite(Path.Combine(destinationDirPath, sourceFi.Name))) | |
{ | |
using (FileStream sourceFs = sourceFi.OpenRead()) | |
{ | |
//await sourceFs.CopyToAsync(destinationFs); | |
int bytesRead; | |
long totalBytesRead = 0; | |
byte[] bytesBuffer = new byte[8 * 1024]; | |
long lengthOfSourceFile = sourceFi.Length; | |
int currentTop = Interlocked.Increment(ref consoleTop); | |
bool firstCall = true; | |
while ((bytesRead = await sourceFs.ReadAsync(bytesBuffer, 0, bytesBuffer.Length)) > 0) | |
{ | |
if (token.IsCancellationRequested) | |
{ | |
token.ThrowIfCancellationRequested(); | |
} | |
await destinationFs.WriteAsync(bytesBuffer, 0, bytesRead); | |
totalBytesRead += bytesRead; | |
ShowProgress(firstCall, message, totalBytesRead, lengthOfSourceFile, currentTop); | |
//You can comment following line to increase copying speed. | |
//await Task.Delay(200); | |
} | |
} | |
} | |
} | |
static void ShowProgress(bool firstCall, string message, long processed, long total, int cursorTop) | |
{ | |
long percent = (100 * (processed + 1)) / total; | |
long characterIndex = (percent + 1) & 3; | |
lock (typeof(Console)) | |
{ | |
int msgLenght = 0; | |
if (firstCall) | |
{ | |
Console.ForegroundColor = ConsoleColor.White; | |
firstCall = false; | |
Console.SetCursorPosition(0, cursorTop); | |
string innerMsg = $"{message}"; | |
msgLenght = innerMsg.Length; | |
Console.Write(innerMsg); | |
} | |
Console.SetCursorPosition(msgLenght, cursorTop); | |
if (percent >= 100) | |
{ | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.Write($"{percent}% [OK]"); | |
} | |
else | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
Console.Write($"{percent}% [{progressCharacters[characterIndex]}]"); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment