2016-09-22 12 views
2

我想讀一個CSV文件,其中頭是3行:如何從CsvHelper的特定行中讀取標題?

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.HasHeaderRecordfalseReadHeader()再次失敗。

+1

大多數CSV閱讀器有一個選項可以跳過第一行以避免標題等。如果CsvReader沒有該選項,只需閱讀幾行,如Evk顯示 –

回答

3

試試這個:

using (var reader = new StreamReader(stream)) { 
     reader.ReadLine(); 
     reader.ReadLine(); 
     using (var csv = new CsvReader(reader)) {      
      csv.ReadHeader();      
    } 
} 
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之前,因爲Read()中的ShouldSkipRecord邏輯位於ReadHeader()邏輯之後。