7

I read the content of a CSV file from a zip file in memory(the requirment is not to write to disk) into the MemoryStream. and use to following code to get the human readable string

 string  result = Encoding.ASCII.GetString(memoryStream.ToArray());

However, we would like the result to be a string[] to map each row in the CSV file.

Is there a way to handle this automatically?

Thanks

Stratford
  • 135
  • 1
  • 1
  • 11
  • possible duplicate of [Parsing CSV files in C#](http://stackoverflow.com/questions/2081418/parsing-csv-files-in-c-sharp) – Tim S. Mar 01 '13 at 17:44

3 Answers3

24

Firstly, there's no need to call ToArray on the memory stream. Just use a StreamReader, and call ReadLine() repeatedly:

memoryStream.Position = 0; // Rewind!
List<string> rows = new List<string>();
// Are you *sure* you want ASCII?
using (var reader = new StreamReader(memoryStream, Encoding.ASCII))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        rows.Add(line);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
10

You can use Split method to split string by newlines:

string[] result = Encoding.
                  ASCII.
                  GetString(memoryStream.ToArray()).
                  Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
Zbigniew
  • 27,184
  • 6
  • 59
  • 66
4

Depending on the contents of your CSV file, this can be a much harder problem than you're giving it credit for.

assume this is your csv:

id, data1, data2
1, some data, more data
2, "This element has a new line
right in the middle of the field", and that can create problems if you're reading line by line

If you simply read this in line by line with reader.ReadLine(), you're not going to get what you want if you happen to have quoted fields with new lines in the middle (which is generally allowed in CSVs). you need something more like this

List<String> results = new List<string>();
StringBuilder nextRow = new StringBuilder();
bool inQuote = false;
char nextChar;
while(reader.ReadChar(out nextChar)){ // pretend ReadChar reads a char into nextChar and returns false when it hits EOF
  if(nextChar == '"'){
    inQuote = !inQuote;
  } else if(!inQuote && nextChar == '\n'){
    results.Add(nextRow.ToString());
    nextRow.Length = 0;
  } else{ nextString.Append(nextChar); }
}

note that this handles double quotes. Missing quotes will be a problem, but they always are in .csv files.

sammy_winter
  • 139
  • 7