Click here to Skip to main content
14,207,581 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


90 bookmarked
Posted 4 Jul 2012
Licenced CPOL

Reading and Writing CSV Files in C#

, 4 Jul 2012
Rate this:
Please Sign up or sign in to vote.
Here's some lightweight C# code for reading and writing CSV files.


A common requirement is to have applications share data with other programs. Although there are interfaces available to work with, for example, Microsoft Excel data files, this approach is generally complex, involves a fair amount of overhead, and requires that support libraries accompany your application.

Comma-Separated Values (CSV) Files

A much simpler way to have your application share data is by reading and writing Comma-Separated Values (CSV) files. CSV files can easily be read and written by many programs, including Microsoft Excel.

For the most part, reading and writing CSV files is trivial. As the name suggestions, a CSV file is simply a plain text file that contains one or more values per line, separated by commas. Each value is a field (or column in a spreadsheet), and each line is a record (or row in a spreadsheet).

However, there is slightly more work involved. Double quotes are used to wrap values that contain commas so that the commas are not interpreted as a value separator. The same is also done for values that contain double quotes. In addition, two double quotes together signify a double quote in the value and not a value separator.

So this seems like a perfect task for a handy little C# class. Listing 1 shows my CsvFileWriter and CsvFileReader classes. 

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ReadWriteCsv
    /// <summary>
    /// Class to store one CSV row
    /// </summary>
    public class CsvRow : List<string>
        public string LineText { get; set; }

    /// <summary>
    /// Class to write data to a CSV file
    /// </summary>
    public class CsvFileWriter : StreamWriter
        public CsvFileWriter(Stream stream)
            : base(stream)

        public CsvFileWriter(string filename)
            : base(filename)

        /// <summary>
        /// Writes a single row to a CSV file.
        /// </summary>
        /// <param name="row">The row to be written</param>
        public void WriteRow(CsvRow row)
            StringBuilder builder = new StringBuilder();
            bool firstColumn = true;
            foreach (string value in row)
                // Add separator if this isn't the first value
                if (!firstColumn)
                // Implement special handling for values that contain comma or quote
                // Enclose in quotes and double up any double quotes
                if (value.IndexOfAny(new char[] { '"', ',' }) != -1)
                    builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));
                firstColumn = false;
            row.LineText = builder.ToString();

    /// <summary>
    /// Class to read data from a CSV file
    /// </summary>
    public class CsvFileReader : StreamReader
        public CsvFileReader(Stream stream)
            : base(stream)

        public CsvFileReader(string filename)
            : base(filename)

        /// <summary>
        /// Reads a row of data from a CSV file
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public bool ReadRow(CsvRow row)
            row.LineText = ReadLine();
            if (String.IsNullOrEmpty(row.LineText))
                return false;

            int pos = 0;
            int rows = 0;

            while (pos < row.LineText.Length)
                string value;

                // Special handling for quoted field
                if (row.LineText[pos] == '"')
                    // Skip initial quote

                    // Parse quoted value
                    int start = pos;
                    while (pos < row.LineText.Length)
                        // Test for quote character
                        if (row.LineText[pos] == '"')
                            // Found one

                            // If two quotes together, keep one
                            // Otherwise, indicates end of value
                            if (pos >= row.LineText.Length || row.LineText[pos] != '"')
                    value = row.LineText.Substring(start, pos - start);
                    value = value.Replace("\"\"", "\"");
                    // Parse unquoted value
                    int start = pos;
                    while (pos < row.LineText.Length && row.LineText[pos] != ',')
                    value = row.LineText.Substring(start, pos - start);

                // Add field to list
                if (rows < row.Count)
                    row[rows] = value;

                // Eat up to and including next comma
                while (pos < row.LineText.Length && row.LineText[pos] != ',')
                if (pos < row.LineText.Length)
            // Delete any unused items
            while (row.Count > rows)

            // Return true if any columns read
            return (row.Count > 0);
Listing 1: CsvFileWriter and CsvFileReader Classes

Because the .NET stream classes generally seem to be split into reading and writing, I decided to follow that pattern with my CSV class and split it into CsvFileWriter and CsvFileReader. This also simplifies the code because neither class needs to worry about which mode the file is in or protect against the user switching modes.

The writer class performs any encoding necessary, as I described above, and the reader class performs any necessary decoding. 

Using the code

Both classes take a CsvRow argument. The CsvRow class derives from List<string>, so it's basically just a list of strings.

When you call CsvFileWriter.WriteRow(), the row argument specifies the string values to write out. And when you call CsvFileReader.ReadRow(), the row argument returns the values that were read in.

CsvFileReader.ReadRow() also places the entire line into the CsvRow.LineText member, just in case the caller wants to inspect that. Finally, CsvFileReader.ReadRow() returns a Boolean value that is false when no values could be read at the current line. Under normal circumstances, this would indicate the end of the file.

Listing 2 demonstrates using the classes. 

void WriteTest()
    // Write sample data to CSV file
    using (CsvFileWriter writer = new CsvFileWriter("WriteTest.csv"))
        for (int i = 0; i < 100; i++)
            CsvRow row = new CsvRow();
            for (int j = 0; j < 5; j++)
                row.Add(String.Format("Column{0}", j));

void ReadTest()
    // Read sample data from CSV file
    using (CsvFileReader reader = new CsvFileReader("ReadTest.csv"))
        CsvRow row = new CsvRow();
        while (reader.ReadRow(row))
            foreach (string s in row)
                Console.Write(" ");
Listing 2: Sample Code to Write and Read CSV files


That's about all there is to it. The classes are fairly simple so I didn't include a sample project. All the code for the classes is shown in Listing 1. Note that this code, as presented, does not handle quoted values that span multiple lines. 

This code should be helpful for anyone wanting an easy way to share data with Microsoft Excel or any other program that can read or write CSV files. 


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jonathan Wood
Black Belt Coder
United States United States
Jonathan Wood has been a software developer for more years than he cares to admit. His current focus is on using C# and ASP.NET MVC to develop website applications, and C++ and MFC to develop desktop applications. His consulting company, SoftCircuits, is known for producing various commercial and shareware products.

Having an entrepreneurial spirit, Jonathan also has a number of other online businesses that he built from scratch such as Black Belt Coder, SC Web Group and others. He also has expertise in designing brands (including graphics and logos) and search-engine optimization (SEO).

Jonathan is always willing to discuss consulting work or joint ventures with people looking to develop software or online businesses.

Comments and Discussions

QuestionCSV reader Pin
michaelcourter2-Aug-18 4:06
membermichaelcourter2-Aug-18 4:06 
QuestionApply globalization to this code Pin
Member 1203908926-Oct-16 0:10
memberMember 1203908926-Oct-16 0:10 
QuestionNice one.. but question Pin
rvp52831-Apr-16 0:21
memberrvp52831-Apr-16 0:21 
PraiseThank you. Perfect, simple code. Pin
Stephen Asher16-Dec-15 22:06
memberStephen Asher16-Dec-15 22:06 
GeneralCSV Parser in .Net library Pin
Habeeb Matrix18-Nov-15 19:44
professionalHabeeb Matrix18-Nov-15 19:44 
Generalthank you very much! Pin
Southmountain24-Oct-15 10:45
memberSouthmountain24-Oct-15 10:45 
Questiona double quote found in a quoted field issue Pin
brian lam29-Jun-15 22:40
memberbrian lam29-Jun-15 22:40 
QuestionNice, concise explanation and code Pin
MitchellBaldwin6-May-15 2:25
memberMitchellBaldwin6-May-15 2:25 
Questionvery helpful Pin
pravin.ovhal30-Mar-15 3:28
memberpravin.ovhal30-Mar-15 3:28 
QuestionRead choosed line from CSV Pin
Member 1051353727-Oct-14 23:27
memberMember 1051353727-Oct-14 23:27 
QuestionThank You Pin
younismo28-Aug-14 2:12
memberyounismo28-Aug-14 2:12 
QuestionThis versus TextFieldParser Pin
Saw Naw25-Jun-14 0:44
memberSaw Naw25-Jun-14 0:44 
GeneralMy vote of 3 Pin
Will_保哥31-May-14 6:08
memberWill_保哥31-May-14 6:08 
GeneralRe: My vote of 3 Pin
Jonathan Wood31-May-14 6:35
memberJonathan Wood31-May-14 6:35 
QuestionUTF-8 Encoding Problem Pin
Christian Rauchenwald21-May-14 4:16
memberChristian Rauchenwald21-May-14 4:16 
AnswerRe: UTF-8 Encoding Problem Pin
Jonathan Wood21-May-14 4:58
memberJonathan Wood21-May-14 4:58 
GeneralRe: UTF-8 Encoding Problem Pin
Pertti Palokangas10-Mar-15 22:48
memberPertti Palokangas10-Mar-15 22:48 
QuestionWorks Great! Pin
Roy Parker1-Apr-14 8:28
memberRoy Parker1-Apr-14 8:28 
QuestionReading and writing csv files Pin
srvishnukumar17-Mar-14 17:46
membersrvishnukumar17-Mar-14 17:46 
Hi Jonathan,

Am very happy to get this article.. i need one more help from you... that is i need to imported (uploaded) CSV file and readed it and have to write the data in another CSV file then exported(download) that files in our local machine..

How can this possible.. if you have the code about this task.. please mail me jonathan.. its Soo help to me.. here am waiting for your mail with code..

Please note my mail id :

Thanks & Regards,
Vishnukumar SR

AnswerRe: Reading and writing csv files Pin
Jonathan Wood17-Mar-14 18:28
memberJonathan Wood17-Mar-14 18:28 
GeneralRe: Reading and writing csv files Pin
srvishnukumar17-Mar-14 22:22
membersrvishnukumar17-Mar-14 22:22 
GeneralRe: Reading and writing csv files Pin
Jonathan Wood18-Mar-14 5:56
memberJonathan Wood18-Mar-14 5:56 
AnswerRe: Reading and writing csv files Pin
HEMANT GOVEKAR16-Apr-19 14:00
memberHEMANT GOVEKAR16-Apr-19 14:00 
QuestionAdd rows to existing csv file Pin
Member 994058312-Dec-13 21:10
memberMember 994058312-Dec-13 21:10 
AnswerRe: Add rows to existing csv file Pin
Jonathan Wood17-Mar-14 18:29
memberJonathan Wood17-Mar-14 18:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190612.1 | Last Updated 4 Jul 2012
Article Copyright 2012 by Jonathan Wood
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid