Mure
Mure

Reputation: 11

C# Read Files location and destination IN CSV and copy to a different folder

I have a CSV file that will be populated with different file names, source and archive location

And I would like to read the CSV file and copy/ Move each file name to an archive and stamp each file moved with date and time in the archive my CSV "test.csv" is like this

Number FileName Source Destination**
1, Support.CSv, C:\home, C:\Support\Archive
2, Account.txt, c:\home, D:\Account\Archive
3, Support5.csv, C:\home, C:\Support\Archive
4, allusers.csv, c:\home, D:\Account\Archive
5, Users2.csv, c:\home, D:\Account\Archive

How can I achieve this , I have tried the below code but all the files are copied in the same directory and this is not what I am looking for

        string sourceDir1;
        string backupDir1;
        var path = @"C:/test.csv";
        using (TextFieldParser csvReader = new TextFieldParser(path))
        {
            csvReader.CommentTokens = new string[] { "#" };
            csvReader.SetDelimiters(new string[] { "," });
            csvReader.HasFieldsEnclosedInQuotes = true;

            // Skip the row with the column names
            csvReader.ReadLine();

            while (!csvReader.EndOfData)
            {
                // Read current line fields, pointer moves to the next line.
                string[] fields = csvReader.ReadFields();
                 String sourceDir = fields[2];
                string backupDir = fields[3];
               

                try
        {

           


            string[] picList = Directory.GetFiles(sourceDir, "*.csv");
            string[] txtList = Directory.GetFiles(sourceDir, "*.txt");
           ;

                    // Copy CSV files.
                    foreach (string f in picList)
            {
                // Remove path from the file name.
                string fName = f.Substring(sourceDir.Length + 1);
                       

                        // Use the Path.Combine method to safely append the file name to the path.
                        // Will overwrite if the destination file already exists.
                        File.Copy(Path.Combine(sourceDir, fName), Path.Combine(backupDir, fName), true);
            }

            // Copy text files.
            foreach (string f in txtList)
            {

                // Remove path from the file name.
                string fName = f.Substring(sourceDir.Length + 1);

                try
                {
                    // Will not overwrite if the destination file already exists.
                    File.Copy(Path.Combine(sourceDir, fName), Path.Combine(backupDir, fName));
                }

                // Catch exception if the file was already copied.
                catch (IOException copyError)
                {
                    Console.WriteLine(copyError.Message);
                }
            }

Upvotes: 1

Views: 929

Answers (1)

tlucian
tlucian

Reputation: 186

There is no need of checking source items on each loop and re-copy items again, you can check if the current file exists and then just copy it to the specific destination. In this case your code will look like this:

        var path = @"C:/test.csv";

        using (TextFieldParser csvReader = new TextFieldParser(path))
        {
            csvReader.CommentTokens = new string[] { "#" };
            csvReader.SetDelimiters(new string[] { "," });
            csvReader.HasFieldsEnclosedInQuotes = true;

            // Skip the row with the column names
            csvReader.ReadLine();

            while (!csvReader.EndOfData)
            {
                // Read current line fields, pointer moves to the next line.
                string[] fields = csvReader.ReadFields();
                string fileName = fields[1];
                string sourceDir = fields[2];
                string backupDir = fields[3];

                try
                {
                    var sourceFilePath = $@"{sourceDir}\{fileName}";

                    var sourceFileExists = File.Exists(sourceFilePath);

                    if (sourceFileExists)
                    {
                        //check if the destination directory exists
                        var destinationDirectory = Directory.Exists($@"{backupDir}");

                        if (!destinationDirectory)
                        {
                            Directory.CreateDirectory($@"{backupDir}");
                        }

                        var destinationFilePath = Path.Combine($@"{backupDir}", fileName);

                        File.Copy(sourceFilePath, destinationFilePath, true);
                    }
                    else
                    {
                        throw new Exception("File was not found");
                    }
                }
                catch(IOException ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }

You will also have to alter the destination file name by adding the timestamp.

Upvotes: 0

Related Questions