I have similar issue on #92. But I'm not sure whether I should've bumped the issue that has been over 5 years old, so I'm creating a new one.
I'm aware that calling Count()
on the enumerated records will cause the cursor goes to the end and further operation/foreach
loop on the records will return nothing.
The outline of my code is like this
````C#
var myCSV = new CsvReader(File.OpenText(txtBox_CSVFile.Text));
myCSV.Configuration.RegisterClassMap
var record = new MyRecordClass();
var allRecords = myCSV.EnumerateRecords(record);
int recordsLength = allRecords.Count<MyRecordClass>();
foreach (var r in allRecords)
{
/* some read/write operation here
*/
scannedCSVEntry++;
progress.value = scannedCSVEntry/recordsLength;
}
````
The recordsLength
is important here as I need to update the progress bar while I'm processing the entry
But how do I get around this?
There are a few ways.
ToList
. You can then do several operations over the data, including Count
.Context.RawRow
property to do your progress.Thanks,
I finally picked method 2.
C#
StreamReader sr = File.OpenText(txtBox_CSVFile.Text);
int recordsLength = 0;
while(sr.ReadLine() != null)
{
++recordsLength;
}
recordsLength--; // discount 1 line because there are column headers in first row.
Console.WriteLine("recordsLength : " + recordsLength);
sr.Close();
Does EnumerateRecords()
automatically close the stream after hydrating all the entries? I'm wondering whether I should call Close()
after calling the function.
My suggestion is to wrap in a using
block.
using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
int recordsLength = 0;
while(sr.ReadLine() != null)
{
++recordsLength;
}
recordsLength--; // discount 1 line because there are column headers in first row.
Console.WriteLine("recordsLength : " + recordsLength);
}
If you want just update progress bar, then using stream.Position
worked for me with large files without reading the entire file first:
using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
var csvReader = new new CsvHelper.CsvReader(sr);
while (csvReader.Read())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
}
it should work also with GetRecords, but I've not tested:
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
I've checked your solution
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
which didn't work for me.
But you can do this
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)csvReader.Context.CharPosition / csvReader.Context.CharsRead;
}
to get the desired result
Most helpful comment
If you want just update progress bar, then using
stream.Position
worked for me with large files without reading the entire file first:it should work also with GetRecords, but I've not tested: