我试图读取标题位于第3行的CSV文件:
some crap line
some empty line
COL1,COL2,COl3,...
val1,val2,val3
val1,val2,val3
如何告诉CSVHelper标题不在第一行?
我尝试使用Read()
跳过2行,但是对ReadHeader()
的后续调用会引发一个异常,即标题已被读取。
using (var csv = new CsvReader(new StreamReader(stream), csvConfiguration)) {
csv.Read();
csv.Read();
csv.ReadHeader();
.....
如果我将csvConfiguration.HasHeaderRecord
设置为false
ReadHeader()
再次失败。
答案 0 :(得分:4)
试试这个:
using (var reader = new StreamReader(stream)) {
reader.ReadLine();
reader.ReadLine();
using (var csv = new CsvReader(reader)) {
csv.ReadHeader();
}
}
答案 1 :(得分:1)
这并不比Evk的答案好,但我很感兴趣。
CsvConfiguration类似乎有一个名为ShouldSkipRecord的Func回调,可以连接到它以实现自定义逻辑。
https://github.com/JoshClose/CsvHelper/tree/master/src/CsvHelper
CsvConfiguration.cs
/// <summary>
/// Gets or sets the callback that will be called to
/// determine whether to skip the given record or not.
/// This overrides the <see cref="SkipEmptyRecords"/> setting.
/// </summary>
public virtual Func<string[], bool> ShouldSkipRecord { get; set; }
CsvReader.cs
/// <summary>
/// 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.
/// </summary>
/// <returns>True if there are more records, otherwise false.</returns>
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;
}
/// <summary>
/// Checks if the current record should be skipped or not.
/// </summary>
/// <returns><c>true</c> if the current record should be skipped, <c>false</c> otherwise.</returns>
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()逻辑。