I have the following code where I look at columns headers before some condition statement:
var csvConfig = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
{
// csvconfig.Delimiter = "\t";
HasHeaderRecord = true
};
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
using (CsvReader csv1 = new CsvReader(reader, csvConfig))
{
CsvReader csv2 = csv1;
csv2.Read();
csv2.ReadHeader();
string[] headers = csv2.HeaderRecord;
if(headers[0].Replace("\0", "").ToUpper() == "TEST")
{
using (var dr1 = new CsvDataReader(csv1))
{
var dt1 = new DataTable();
dt1.Load(dr1);
}
}
}
I thought that by having 2 variables for the CsvReader (csv1 and csv2) it would be feasible but it seems that they both use the same object in memory. Therefore when I want to use csv2 to fill my datatable, the header row has been already read in csv1 and is not loaded in my datatable.
How can I make sure that csv2 contains the whole csv and is distinct from csv1? Is there a method to go back to the beginning or do I need to read the whole CSV again using CsvReader?
Thank you
CodePudding user response:
In C#, datas types are categorized based on how they store their value in the memory : by value or by reference (by pointer exists too).
For example, a string is usually stored by value but complex objects like your reader are almost always stored by reference.
When you do csv2 = csv1
both now refer to the same memory area. This means that they are 2 names for the same thing. When you do an action on csv1, csv2 also receives it since they are 2 aliases for the same information.
Try if CSVreader implements Clone() :
CsvReader csv2 = csv1.Clone();
If it is, the function will create a new object with the same informations which do not share the same memory area.
CodePudding user response:
You need a separate CsvReader
for csv1
and csv2
. As both you @UserNam3 advise, you don't want csv2
to be referencing the same object as csv1
in memory. They will both be using the same Stream
, so after reading the header with csv2
you will need to reset the Stream
back to the beginning.
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
using (CsvReader csv1 = new CsvReader(reader, csvConfig))
using (CsvReader csv2 = new CsvReader(reader, csvConfig))
{
csv2.Read();
csv2.ReadHeader();
string[] headers = csv2.HeaderRecord;
reader.BaseStream.Position = 0;
if(headers[0].Replace("\0", "").ToUpper() == "TEST")
{
using (var dr1 = new CsvDataReader(csv1))
{
var dt1 = new DataTable();
dt1.Load(dr1);
}
}
}