Skip to content

Instantly share code, notes, and snippets.

@kenanhancer
Created February 27, 2018 23:59
Show Gist options
  • Save kenanhancer/33266e42814e156aba6e7b4a2b54c641 to your computer and use it in GitHub Desktop.
Save kenanhancer/33266e42814e156aba6e7b4a2b54c641 to your computer and use it in GitHub Desktop.
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