从 CsvHelper 27.0 开始,该问题不再重现。现在可以从任何行读取标题。根据change log,这可能早在Release 3.0.0 from 2017 就已实现:
3.0.0
读取超过 1 个标题行。
因此,以下代码现在可以正常工作,并且已经工作了一段时间:
var csvText = "some crap line\nsome empty line\nCOL1,COL2,COl3\nval1,val2,val3\nval1,val2,val3\n\n";
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(csvText));
var csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
{
// Your settings here.
};
using (var csv = new CsvReader(new StreamReader(stream), csvConfiguration))
{
csv.Read(); // Read in the first row "some crap line"
csv.Read(); // Read in the second row "some empty line"
csv.Read(); // Read in the third row which is the actual header.
csv.ReadHeader(); // Process the currently read row as the header.
Assert.AreEqual(3, csv.HeaderRecord.Length);
Assert.AreEqual(@"COL1,COL2,COl3", String.Join(",", csv.HeaderRecord));
成功的演示小提琴 #1 here.
警告:请注意 CsvHelper 默认跳过空白行,因此如果要跳过的某些初步行可能为空白,也可能不为空白,csv.Read() 可能默默地阅读它们——然后也使用你的标题,导致错误的行被用作标题行!
演示小提琴 #2 here 失败。
为避免这种可能性并确定性地在文件开头跳过一定数量的行,您必须设置CsvConfiguration.IgnoreBlankLines = false。但是,一旦创建了CsvReader,就无法修改此属性,因此如果您需要跳过空白数据行,可以使用ShouldSkipRecord 回调来完成:
bool ignoreBlankLines = false;
var csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
{
IgnoreBlankLines = false,
ShouldSkipRecord = (args) => !ignoreBlankLines ? false : args.Record.Length == 0 || args.Record.Length == 1 && string.IsNullOrEmpty(args.Record[0]),
// Your settings here.
};
using (var csv = new CsvReader(new StreamReader(stream), csvConfiguration))
{
csv.Read(); // Read in the first row "some crap line"
csv.Read(); // Read in the second empty row, which is empty.
csv.Read(); // Read in the third row which is the actual header.
csv.ReadHeader(); // Process the currently read row as the header.
ignoreBlankLines = true; // Now that the header has been read, ignore blank data lines.
成功的演示小提琴#3 here.