CSV reader

using System;
using System.Collections;
using System.Data;
using System.Text;
using System.IO;
 
namespace SomeNamespace
{
    static class CsvReader
    {
        public static DataTable Parse(TextReader stream, bool headers)
        {
            DataTable table = new DataTable();
 
            CsvStream csv = new CsvStream(stream);
            string[] row = csv.GetNextRow();
            if (row == null)
                return null;
            if (headers)
            {
                foreach (string header in row)
                {
                    if (header != null && header.Length > 0 && !table.Columns.Contains(header))
                        table.Columns.Add(header, typeof(string));
                    else
                        table.Columns.Add(GetNextColumnHeader(table), typeof(string));
                }
                row = csv.GetNextRow();
            }
            while (row != null)
            {
                while (row.Length > table.Columns.Count)
                    table.Columns.Add(GetNextColumnHeader(table), typeof(string));
                table.Rows.Add(row);
                row = csv.GetNextRow();
            }
            return table;
        }
 
        private static string GetNextColumnHeader(DataTable table)
        {
            int c = 1;
            while (true)
            {
                string h = "Column" + c++;
                if (!table.Columns.Contains(h))
                    return h;
            }
        }
    }
 
    class CsvStream
    {
        private TextReader stream;                 
 
        public CsvStream(TextReader s)
        {
            this.stream = s;
        }
 
        public string[] GetNextRow()
        {
            ArrayList row = new ArrayList();
 
            while (true)
            {
                string item = GetNextItem();
                if (item == null)
                        return row.Count == 0 ? null : (string[])row.ToArray(typeof(string));
                row.Add(item);
            }
        }
 
        private bool EOS = false;
        private bool EOL = false;
 
        private string GetNextItem()
        {
            if (EOL)
            {
                // previous item was last in line, start new line
                EOL = false;
                return null;
            }
 
            bool quoted = false;
            bool predata = true;
            bool postdata = false;
 
            StringBuilder item = new StringBuilder();
 
            while (true)
            {
                char c = GetNextChar(true);
                if (EOS)
                        return item.Length > 0 ? item.ToString() : null;
 
                if ((postdata || !quoted) && c == ';')
                    // end of item, return
                    return item.ToString();
 
                if ((predata || postdata || !quoted) && (c == '\x0A' || c == '\x0D'))
                {
                    // we are at the end of the line, eat newline characters and exit
                    EOL = true;
                    if (c == '\x0D' && GetNextChar(false) == '\x0A')
                            // new line sequence is 0D0A
                            GetNextChar(true);
                    return item.ToString();
                }
 
                if (predata && c == ' ')
                    // whitespace preceeding data, discard
                    continue;
 
                if (predata && c == '"')
                {
                    // quoted data is starting
                    quoted = true;
                    predata = false;
                    continue;
                }
 
                if (predata)
                {
                    // data is starting without quotes
                    predata = false;
                    item.Append(c);
                    continue;
                }
 
                if (c == '"' && quoted)
                {
                    if (GetNextChar(false) == '"')
                            // double quotes within quoted string means add a quote       
                            item.Append(GetNextChar(true));
                    else
                            // end-quote reached
                            postdata = true;
                    continue;
                }
 
                // all cases covered, character must be data
                item.Append(c);
            }
        }
 
        private char[] buffer = new char[4096];
        private int pos = 0;
        private int length = 0;
 
        private char GetNextChar(bool eat)
        {
            if (pos >= length)
            {
                    length = stream.ReadBlock(buffer, 0, buffer.Length);
                    if (length == 0)
                    {
                            EOS = true;
                            return '\0';
                    }
                    pos = 0;
            }
 
            if (eat)
                    return buffer[pos++];
            else
                    return buffer[pos];
        }
    }
}
 
 
 

Download this snippet

Class for accessing and reading CSV (comma seperated values) files.

Twitter Twitter

2 Comments to “ CSV reader”

  1. Anonymous  on Mar 14, 2010

    Nh9Gz4 <a href="http://xiwgzbypxolh.com/">xiwgzbypxolh</a>, [url=http://fhdaoteodcfm.com/]fhdaoteodcfm[/url], [link=http://riquixqzkdst.com/]riquixqzkdst[/link], http://plqheghvvikv.com/

  2. Anonymous  on Jun 10, 2010

    UNdkhr <a href="http://hqjpkjaodhep.com/">hqjpkjaodhep</a>, [url=http://jvonfrxgnhhm.com/]jvonfrxgnhhm[/url], [link=http://esyqvubefais.com/]esyqvubefais[/link], http://cmvmhossyofe.com/

Leave a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>