How to parse CSV files in C#

John Avis by | February 16, 2020 | C#

A simple C# class that parses CSV files.
There's various ways to parse CSV files. Some don't always work well and some do work well but are bigger than you might want.

This is a simple C# class that can read a CSV file line by line and provide the row's column values in a List<string>.

It can handle values with or without delimiters (quotation marks), and carriage returns/line feeds within delimited values.

Usage example:

CsvReader file = new CsvReader(Server.MapPath("file.csv"));

while (!file.EndOfFile)
{
List<string> row = file.Read();

if (row != null)
{
//do something with each cell, eg. row[0]
}
}

file.Close();


The class:

public class CsvReader
{
private StreamReader _reader;

private bool _endOfFile;

public bool EndOfFile
{
get
{
return this._endOfFile;
}
}

public CsvReader(string file)
{
this._endOfFile = false;
this._reader = new StreamReader(file);
}

public List<string> Read()
{
if (this._endOfFile)
{
return null;
}

string line = this._reader.ReadLine();

if (line == null)
{
this._endOfFile = true;

return null;
}

List<string> result = new List<string>();

bool inDelimiters = false;

int startPos = 0;

int pos = 0;

while (pos <= line.Length)
{
string chr = (pos < line.Length ? line.Substring(pos, 1) : null);

if (chr == "\"" && !inDelimiters && pos == startPos)
{
inDelimiters = true;
}
else if (chr == "\"" && inDelimiters)
{
if (pos == line.Length - 1)
{
result.Add(line.Substring(startPos + 1, pos - (startPos + 1)).Replace("\"\"", "\""));

break;
}
else if (line.Substring(pos + 1, 1) == ",")
{
result.Add(line.Substring(startPos + 1, pos - (startPos + 1)).Replace("\"\"", "\""));

pos++;

startPos = pos + 1;

inDelimiters = false;
}
else if (line.Substring(pos + 1, 1) == "\"")
{
pos++;

if (pos == (line.Length - 1))
{
string nextLine = this._reader.ReadLine();

if (nextLine == null)
{
throw new Exception("CSV file is invalid");
}

line += "\n" + nextLine;
}
}
}
else if (chr == "," && !inDelimiters)
{
result.Add(line.Substring(startPos, pos - startPos));

startPos = pos + 1;
}
else if (pos == (line.Length - 1) && inDelimiters)
{
string nextLine = this._reader.ReadLine();

if (nextLine == null)
{
throw new Exception("CSV file is invalid");
}

line += "\n" + nextLine;
}
else if (pos == line.Length - 1)
{
result.Add(line.Substring(startPos, (pos + 1) - startPos));

break;
}

pos++;
}

return result;
}

public void Close()
{
if (this._reader != null)
{
this._reader.Close();
this._reader = null;
}
}

~CsvReader()
{
this.Close();
}
}

Related Posts

Search result highlighting and truncation in C#

by John Avis | February 3, 2016

Isn't it nice how search engines show a brief section of content with your search terms highlighted in search results?

Comments

There are no comments yet. Be the first to leave a comment!

Leave a Comment

Tags

About

...random postings about web development and programming, Internet, computers and electronics topics.

I recommend ASPnix for web hosting and Crazy Domains for domain registration.

Subscribe

Get the latest posts delivered to your inbox.