using System.Collections.Generic;
using System.Threading.Tasks;
static int Main(string[] args)
if(!File.Exists(args[0]))
Console.WriteLine("Source file list does not exist: " + args[0]);
if(!Directory.Exists(args[1]))
Console.WriteLine("Destination directory does not exist: " + args[1]);
string SourceFilePath = args[0];
string DestinationDir = args[1];
if (!DestinationDir.EndsWith("\\"))
DestinationDir = DestinationDir + "\\";
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
po.MaxDegreeOfParallelism = Environment.ProcessorCount*2;
string[] FilesToMove = File.ReadAllLines(args[0]);
object LockerObj = new object();
List<string> Errors = new List<string>();
DrawProgressBar(Progress, FilesToMove.Length, 25, '*');
Parallel.ForEach(FilesToMove, po, (line, loopState) =>
Interlocked.Increment(ref Progress);
DrawProgressBar(Progress, FilesToMove.Length, 25, '*');
File.Copy(line, DestinationDir + Path.GetFileName(line), true);
catch(FileNotFoundException)
catch (System.Exception ex)
Errors.Add(ex.GetType().ToString() + ": " + ex.Message);
if (!loopState.IsStopped)
foreach (string e in Errors)
private static void ShowUsage(string ProgramName)
Console.WriteLine(ProgramName + " <FullFilePathsList.txt> <DestinationDirectory>");
Console.WriteLine("Example: " + ProgramName + " files.txt C:\\test");
public static void DrawProgressBar(int complete, int maxVal, int barSize, char progressCharacter)
Console.CursorVisible = false;
int left = Console.CursorLeft;
decimal perc = (decimal)complete / (decimal)maxVal;
int chars = (int)Math.Floor(perc / ((decimal)1 / (decimal)barSize));
string p1 = String.Empty, p2 = String.Empty;
for (int i = 0; i < chars; i++) p1 += progressCharacter;
for (int i = 0; i < barSize - chars; i++) p2 += progressCharacter;
Console.ForegroundColor = ConsoleColor.Green;
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write(" {0}%", (perc * 100).ToString("N2"));
Console.CursorLeft = left;