CodeXchange Tuesday, March 19, 2019
What's it?
My Snippets
Add Snippet
Contact Us

Website hosted by

Code Snippet Preview

Review the code snippet before inserting it on your project.

Snippet Metadata
Summary: CSV parser for C#
Language: C#
Author: J.Marc Piulachs
Author snippets RSS:
Culture: en-US
Bytes: 5166
Visual Studio 2005 Snippet:

Snippet Stats
Downloads: 25
Overall rating : 0
Average rating : Snippet rating

Snippet Preview
using System;
using System.Collections;
using System.IO;
using System.Text;
namespace JouniHeikniemi.Tools.Text {
  /// A data-reader style interface for reading CSV files.
  public class CSVReader : IDisposable {
    #region Private variables
    private Stream stream;
    private StreamReader reader;
    /// Create a new reader for the given stream.
    /// The stream to read the CSV from.
    public CSVReader(Stream s) : this(s, null) { }
    /// Create a new reader for the given stream and encoding.
    /// The stream to read the CSV from.
    /// The encoding used.
    public CSVReader(Stream s, Encoding enc) { = s;
      if (!s.CanRead) {
        throw new CSVReaderException("Could not read the given CSV stream!");
      reader = (enc != null) ? new StreamReader(s, enc) : new StreamReader(s);
    /// Creates a new reader for the given text file path.
    /// The name of the file to be read.
    public CSVReader(string filename) : this(filename, null) { }
    /// Creates a new reader for the given text file path and encoding.
    /// The name of the file to be read.
    /// The encoding used.
    public CSVReader(string filename, Encoding enc) 
      : this(new FileStream(filename, FileMode.Open), enc) { }
    /// Returns the fields for the next row of CSV data (or null if at eof)
    /// A string array of fields or null if at the end of file.
    public string[] GetCSVLine() {
      string data = reader.ReadLine();
      if (data == null) return null;
      if (data.Length == 0) return new string[0];
      ArrayList result = new ArrayList();
      ParseCSVFields(result, data);
      return (string[])result.ToArray(typeof(string));
    // Parses the CSV fields and pushes the fields into the result arraylist
    private void ParseCSVFields(ArrayList result, string data) {
      int pos = -1;
      while (pos < data.Length)
        result.Add(ParseCSVField(data, ref pos));
    // Parses the field at the given position of the data, modified pos to match
    // the first unparsed position and returns the parsed field
    private string ParseCSVField(string data, ref int startSeparatorPosition) {
      if (startSeparatorPosition == data.Length-1) {
        // The last field is empty
        return "";
      int fromPos = startSeparatorPosition + 1;
      // Determine if this is a quoted field
      if (data[fromPos] == '"') {
        // If we're at the end of the string, let's consider this a field that
        // only contains the quote
        if (fromPos == data.Length-1) {
          return "\"";
        // Otherwise, return a string of appropriate length with double quotes collapsed
        // Note that FSQ returns data.Length if no single quote was found
        int nextSingleQuote = FindSingleQuote(data, fromPos+1);
        startSeparatorPosition = nextSingleQuote+1;
        return data.Substring(fromPos+1, nextSingleQuote-fromPos-1).Replace("\"\"", "\"");
      // The field ends in the next comma or EOL
      int nextComma = data.IndexOf(',', fromPos);
      if (nextComma == -1) {
        startSeparatorPosition = data.Length;
        return data.Substring(fromPos);
      else {
        startSeparatorPosition = nextComma;
        return data.Substring(fromPos, nextComma-fromPos);
    // Returns the index of the next single quote mark in the string 
    // (starting from startFrom)
    private int FindSingleQuote(string data, int startFrom) {
      int i = startFrom-1;
      while (++i < data.Length)
        if (data[i] == '"') {
          // If this is a double quote, bypass the chars
          if (i < data.Length-1 && data[i+1] == '"') {
            return i;
      // If no quote found, return the end value of i (data.Length)
      return i;
    /// Disposes the CSVReader. The underlying stream is closed.
    public void Dispose() {
      // Closing the reader closes the underlying stream, too
      if (reader != null) reader.Close();
      else if (stream != null)
        stream.Close(); // In case we failed before the reader was constructed

  /// Exception class for CSVReader exceptions.
  public class CSVReaderException : ApplicationException { 
    /// Constructs a new exception object with the given message.
    /// The exception message.
    public CSVReaderException(string message) : base(message) { }

Snippet Comments
No comments for this snippet

Other snippets that may interest you..
Related Snippets
TDT - GridPage - Page_Init (C#)
CustomValitaor (C#)
Get the file extension from a file path or file name (VB.NET)
grab record from db and subtracts it from variable (VB.NET)

Copyright ©2009-2019 CodeXchange. Server version 1.0.3720.32855 Client Version

With from Barcelona

Most Helpful members
These are the members who have received the most points for their helpful samples
Zepho Zep
Robert Wagner
Galen Taylor

All time 'Hall of fame'
Formating a file size and adding the B, KB, MB and GB extension appropriately with string.Format (C#)
INI File Access (VB.NET)
Read XML from string into DataSet (C#)
Create Manifest File for your Application (VB.NET)
Round function to avoid banker's rounding (VB.NET)
Get Short and Long Path Names (VB.NET)
Sending Mail through authenticated SMTP server (C#)
One Way Hash for strings (C#)
Formating a file size and adding the B, KB, MB and GB extension appropriately with string.Format (C#)
How do I load an image from a URI address? (VB.NET)
Use our easy to use Visual Studio.NET addin client and start sharing code snippets with the CodeXchange community!
Refreshed: Tuesday, March 19, 2019