Created
September 19, 2012 19:05
-
-
Save praeclarum/3751553 to your computer and use it in GitHub Desktop.
CSV Reader - I never want to write this again
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Collections.Generic; | |
using System.Text; | |
namespace ClosedQuestions | |
{ | |
public class Record | |
{ | |
string[] data; | |
public Record (int length) | |
{ | |
data = new string[length]; | |
} | |
public string this[int index] { | |
get { | |
return data[index]; | |
} | |
set { | |
data[index] = value; | |
} | |
} | |
public override string ToString () | |
{ | |
return string.Join (",", data); | |
} | |
} | |
public class CsvReader | |
{ | |
TextReader reader; | |
string[] headers; | |
public CsvReader (TextReader reader) | |
{ | |
this.reader = reader; | |
} | |
public IEnumerable<Record> Records | |
{ | |
get { | |
headers = reader.ReadLine ().Split (','); | |
var r = new Record (headers.Length); | |
var i = 0; | |
var ch = reader.Read (); | |
while (ch > 0) { | |
if (ch == '\n') { | |
yield return r; | |
r = new Record (headers.Length); | |
i = 0; | |
ch = reader.Read (); | |
} | |
else if (ch == '\r') { | |
ch = reader.Read (); | |
} | |
else if (ch == '"') { | |
ch = ReadQuoted (r, i); | |
} | |
else if (ch == ',') { | |
i++; | |
ch = reader.Read (); | |
} | |
else { | |
ch = ReadNonQuoted (r, i, (char)ch); | |
} | |
} | |
} | |
} | |
int ReadNonQuoted (Record r, int index, char first) | |
{ | |
var sb = new StringBuilder (); | |
sb.Append (first); | |
var ch = reader.Read (); | |
while (ch >= 0 && ch != ',' && ch != '\r' && ch != '\n') { | |
sb.Append ((char)ch); | |
ch = reader.Read (); | |
} | |
r[index] = sb.ToString (); | |
return ch; | |
} | |
int ReadQuoted (Record r, int index) | |
{ | |
var sb = new StringBuilder (); | |
var ch = reader.Read (); | |
var hasQuote = false; | |
while (ch >= 0) { | |
if (ch == '"') { | |
if (hasQuote) { | |
sb.Append ('"'); | |
hasQuote = false; | |
} | |
else { | |
hasQuote = true; | |
} | |
} | |
else { | |
if (hasQuote) { | |
r[index] = sb.ToString (); | |
return ch; | |
} | |
else { | |
sb.Append ((char)ch); | |
} | |
} | |
ch = reader.Read (); | |
} | |
r[index] = sb.ToString (); | |
return ch; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is so wrong with this: http://kbcsv.codeplex.com/ that you had to write 133 lines of code?