如何使用 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>();
}
我正在尝试读取以下格式的 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>();
}