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.Positionworked for me with large files without reading the entire file first:it should work also with GetRecords, but I've not tested: