none
TextFieldParser cannot reliably return the LineNumber RRS feed

  • Question

  • The TextFieldParser class is a fantastic component for reading CSV files. However it has a flaw regarding LineNumber.

    If the CSV file contains blank lines, there is no way to reliably get the LineNumber where data came from, particularly for the last line.

    The LineNumber property holds the line number of the row where the parser will look for data on the next call to ReadFields. However, if there are blank lines, then they will be skipped over by ReadFields before returning the result. So checking before calling ReadFields is no good.

    After calling ReadFields, the LineNumber is already advanced beyond the source of the row (in contradiction to the example provided on the MSDN docs for TextFieldParser.LineNumber). One could potentially just subtract 1 from this number, except if it was the last row, then the line number holds -1. So it's actually impossible to get the line number of the last row, if it was preceeded by blank spaces.

    using System;
    using System.IO;
    using Microsoft.VisualBasic.FileIO;
    ...
    string csv = "\r\nline2\r\n\r\n\r\nline5";
    var reader = new StringReader( csv );
    var parser = new TextFieldParser( reader )
    {
        Delimiters = new [ ] { "," }
    };
    Console.WriteLine( parser.LineNumber );           // gives 1
    Console.WriteLine( parser.ReadFields( ) [ 0 ] );  // gives "line2"
    Console.WriteLine( parser.LineNumber );           // gives 3
    Console.WriteLine( parser.ReadFields( ) [ 0 ] );  // gives "line5"
    Console.WriteLine( parser.LineNumber );           // gives -1
    
    // In this example, the field-value shows the actual
    // line number that the data appeared on.
    // But it is not possible to retrieve this from the LineNumber
    // property, either before or after ReadFields is called


    It would be good if TextFileParser could have an option to not automatically skip blank lines and/or have a property to get the LineNumber of the last row read.

    parser.ReadFields() -> ["Line4"]

    parser.LineNumber -> 5

    Friday, April 29, 2016 12:49 AM

Answers

  • I do not think that subtracting 1 can be applied in case of multiline values (with quotation marks), such as:

        string csv = "...\"multiline\r\ntext\"\r\n...";

    If you really need empty values in such one-column CSV and the files are generated by you, then use empty strings with quotation marks instead of blank lines.

    Saturday, April 30, 2016 4:44 PM

All replies

  • Hi,

    Kindly refer the code below:

    Wish code below will help you.

    string csv = "\r\nline2\r\n\r\n\r\nline5";
    var reader = new StringReader( csv );
    var parser = new TextFieldParser(reader)
    {
        Delimiters = new [ ] { "," }
    };
    
    Int64 lineNumber = 0;
    while (!parser.EndOfData)
    {
        lineNumber = parser.LineNumber;
        var val = parser.ReadLine();
        Console.WriteLine(val);
        
    }
    Console.WriteLine("Total no# of Line:{0}",lineNumber);

    Thanks


    • Edited by stef chui Friday, April 29, 2016 2:14 AM put cvs value
    Friday, April 29, 2016 2:11 AM
  • I do not think that subtracting 1 can be applied in case of multiline values (with quotation marks), such as:

        string csv = "...\"multiline\r\ntext\"\r\n...";

    If you really need empty values in such one-column CSV and the files are generated by you, then use empty strings with quotation marks instead of blank lines.

    Saturday, April 30, 2016 4:44 PM