如何使用CsvHelper读取特定行的标题?
我正在尝试读取标题位于第3行的CSV文件:
some crap line some empty line COL1,COL2,COl3,... val1,val2,val3 val1,val2,val3
如何告诉CSVHelper标题不在第一行?
我尝试使用Read()
跳过2行,但是对ReadHeader()
的后续调用会抛出一个已经读取了标头的exception。
using (var csv = new CsvReader(new StreamReader(stream), csvConfiguration)) { csv.Read(); csv.Read(); csv.ReadHeader(); .....
如果我将csvConfiguration.HasHeaderRecord
设置为false
ReadHeader()
再次失败。
试试这个:
using (var reader = new StreamReader(stream)) { reader.ReadLine(); reader.ReadLine(); using (var csv = new CsvReader(reader)) { csv.ReadHeader(); } }
这并不比Evk的答案好,但我很感兴趣。
CsvConfiguration类似乎有一个名为ShouldSkipRecord的Func回调,它可以连接到实现自定义逻辑。
https://github.com/JoshClose/CsvHelper/tree/master/src/CsvHelper
CsvConfiguration.cs
/// /// Gets or sets the callback that will be called to /// determine whether to skip the given record or not. /// This overrides the setting. /// public virtual Func ShouldSkipRecord { get; set; }
CsvReader.cs
/// /// Advances the reader to the next record. /// If HasHeaderRecord is true (true by default), the first record of /// the CSV file will be automatically read in as the header record /// and the second record will be returned. /// /// True if there are more records, otherwise false. public virtual bool Read() { if (doneReading) { throw new CsvReaderException(DoneReadingExceptionMessage); } if (configuration.HasHeaderRecord && headerRecord == null) { ReadHeader(); } do { currentRecord = parser.Read(); } while (ShouldSkipRecord()); currentIndex = -1; hasBeenRead = true; if (currentRecord == null) { doneReading = true; } return currentRecord != null; } /// /// Checks if the current record should be skipped or not. /// /// true if the current record should be skipped, false otherwise. protected virtual bool ShouldSkipRecord() { if (currentRecord == null) { return false; } return configuration.ShouldSkipRecord != null ? configuration.ShouldSkipRecord(currentRecord) : configuration.SkipEmptyRecords && IsRecordEmpty(false); }
不幸的是,你似乎必须将HasHeaderRecord设置为false,然后在调用ReadHeaders或在第三行调用Read之前将其设置为true,因为Read()中的ShouldSkipRecord逻辑位于ReadHeader()逻辑之后。