Reputation: 11
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
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