TextFieldParser - retrieve line read by ReadFields

1.6k Views Asked by At

I am reading from text files and each row is supposed to have at least 9 fields. Some of the data has only 5 fields, so ReadFields() works and I get an exception when accessing fields[8]. I would prefer to throw a custom exception showing the line that was not complete.

TextFieldParse does not appear to have a property for the retrieving the line that ReadFields() just processed.

        using (var parser = new TextFieldParser(filename))
        {
            parser.HasFieldsEnclosedInQuotes = true;
            parser.TextFieldType = FieldType.Delimited;
            parser.SetDelimiters(",");

            while (!parser.EndOfData)
            {
                linenum++;
                var fields = parser.ReadFields();  // fields 0...N

want to add exception here that messages back the 'short' line

                if (fields.length < 10) {
                  rawline = ????
                  throw new Exception ("ERROR: " + filename 
                      + " not enough data at [" + rawline + "]"
                  );
                }                

normal processing

                string name = fields[0];
                double cost = Convert.ToDouble(fields[8]);
                // ... add info to a list
            }
        }

One possibility would be to use a TextReader to read each line, and a new TextFieldParser for each line as a MemoryStream -- seems like too much

        using (var reader = new StreamReader(filename))
        {
            var line = reader.ReadLine();

            // new Parser and Stream for every line, bleah!
            using (var parser = new TextFieldParser(
                             new MemoryStream(Encoding.ASCII.GetBytes(line))))
            {
                parser.HasFieldsEnclosedInQuotes = true;
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");

                var fields = parser.ReadFields();
                if (fields.Length < 9)
                {
                    throw new Exception("too few fields: " + line);
                }
            }
        }

Are there other, more reasonable, approaches ?

1

There are 1 best solutions below

1
Zohar Peled On

What about string.Join?

while (!parser.EndOfData)
{
    linenum++;
    var fields = parser.ReadFields();  // fields 0...N
    if (fields.length < 10) 
    {
        var rawline = string.Join(",", fields);
        throw new Exception ("ERROR: " + filename 
                  + " not enough data at [" + rawline + "]");
    } 
// ... rest of the code here

Notes:

  1. I'm not sure how the parser returns fields surrounded with " - do they return with the " or without it, and do you even care about that?

  2. Unless encountering such rows means you no longer need to process the rest of the file, I wouldn't throw an exception just yet. You might want to store a list of exceptions and throw a single aggregate exception at the end of the function if that list is not empty.