如何使用 CsvHelper 跳过 csv 文件末尾的脚注

How to skip a footnote at the end of csv file using CsvHelper

我正在尝试读取以下格式的 CSV 文件:

Date Value
12/1/2020 1
12/2/2020 2

文件末尾有一个全为文本的脚注。

如果我使用:

void Main()
{
    using (var reader = new StreamReader("path\to\file.csv"))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        var records = csv.GetRecords<Foo>();
    }
}

public class Foo
{
    public DateTime Date { get; set; }
    public double Value { get; set; }
}

CsvHelper 抛出“FormatException:字符串未被识别为有效的 DateTime。有一个从索引 0 开始的未知单词。”

如果我使用它会起作用:

while (csv.Read()) {
   try {
        records.Add(csv.GetRecord<Foo>());
    }
    catch (Exception e) {}
}

但这真的很慢。

我希望添加:

csv.Configuration.ShouldSkipRecord = record => record.Contains("The");

会解决问题,但我得到同样的错误。

如有任何建议,我们将不胜感激。 (很抱歉无法正确格式化 table。)

您可以定义用于表示注释行的字符:

var configuration = new CsvConfiguration { AllowComments = true, Comment = '#' };
using (var csv = new CsvReader(new StreamReader("path\to\file.csv"), configuration))
{
    var records = csv.GetRecords<Foo>();
}

但这需要你可以操作csv文件或者最后一行的第一个字符是唯一的。

如果脚注只是文本 The,那么您所拥有的就可以了。要完成您想要做的事情,您需要执行以下操作:

csv.Configuration.ShouldSkipRecord = record => record.FirstOrDefault()?.StartsWith("The") ?? false;

您可以测试是否也只有 1 个(或更少)字段。

csv.Configuration.ShouldSkipRecord = record => record.Count() <= 1;

如果您的 CSV 很大,即使使用最基本的 record.Length 检查,ShouldSkipRecord 也可以将处理时间增加 10-20 倍。

@dontbyteme 的解决方案给了我一个想法。只需将注释字符设置为字母 T。这应该不会影响性能并为您提供所需的结果。

var configuration = new CsvConfiguration { AllowComments = true, Comment = 'T' };
using (var csv = new CsvReader(new StreamReader("path\to\file.csv"), configuration))
{
    var records = csv.GetRecords<Foo>();
}