Search code examples
csvhelper

CsvHelper: is it possible to skip last row if it can't be casted?


I would like to read the data from a CSV file with CsvHelper.

The first column is a decimal, so in my class where to store the record is a decimal.

However, sometimes the last row which this first column can't be cast to decimal, because it is $Count followed by the number of data rows, so I get an exception because it can't be casted. And I mean sometimes, so not always this row is created.

My question is, is it possible to configure CsvHelper in the way that if is this last row, skip it and don't create a record for this?

By the moment this is my code:

program.cs

using (var fs = new FileStream(@"D:\temp\csv\ALARM0_.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader reader = new StreamReader(fs))


using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{


    MP370Log record = new MP370Log();
    IEnumerable<MP370Log> records = csv.EnumerateRecords(record);
    int count = records.Count();
    foreach (MP370Log r in records)
    {
        // r is the same instance as record.
    }
}

And this is my class where is stored a row:

public class MP370Log
{
    public decimal? Time_ms { get; set; }
    public int? MsgProc { get; set; }
    public int? StateAfter { get; set; }
    public int? MsgClass { get; set; }
    public int? MsgNumber { get; set; }
    public string? Var1 { get; set; }
    public string? Var2 { get; set; }
    public string? Var3 { get; set; }
    public string? Var4 { get; set; }
    public string? Var5 { get; set; }
    public string? Var6 { get; set; }
    public string? Var7 { get; set; }
    public string? Var8 { get; set; }
    public DateTime? TimeString { get; set; }
    public string? MsgText { get; set; }
    public string? PLC { get; set; }
}

Thanks.


Solution

  • If you know that first column will always begin with "$Count", you could use ShouldSkipRecord.

    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        ShouldSkipRecord = args => args.Row.GetField(0).StartsWith("$Count")
    };
    
    using (var fs = new FileStream(@"D:\temp\csv\ALARM0_.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using (StreamReader reader = new StreamReader(fs))
    using (CsvReader csv = new CsvReader(reader, config))