You can initialize the MemoryStream
from an array to begin with; then you don't have to write anything to a stream. Since Base64, by definition, is pure ascii text, you just convert the input string to bytes using ASCII encoding.
Though, if you're parsing CSV, there are better output options than just text read line by line. Technically, CSV format can contain line breaks inside fields, a feature supported by pretty much anything that writes CSV from spreadsheet files (like MS Excel). To support this, the line-by-line-reading approach is too simple. The .Net framework contains a native CSV reader, though, albeit hidden quite well in the Microsoft.VisualBasic
classes. Since .Net is one framework, though, there's nothing preventing you from adding the reference and using it in C#. The class is TextFieldParser
, from Microsoft.VisualBasic.FileIO
.
public static List<String[]> ParseBase64Csv(String data, Encoding encoding, Char separator, Boolean ignoreEmptyLines)
{
List<String[]> splitLines = new List<String[]>();
using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(data)))
using (FromBase64Transform tr = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
using (CryptoStream cs = new CryptoStream(ms, tr, CryptoStreamMode.Read))
using (StreamReader sr = new StreamReader(cs, encoding))
using (TextFieldParser tfp = new TextFieldParser(sr))
{
tfp.TextFieldType = FieldType.Delimited;
tfp.Delimiters = new String[] { separator.ToString() };
while (true)
{
try
{
String[] curLine = tfp.ReadFields();
if (curLine == null)
break;
if (ignoreEmptyLines && (curLine.Length == 0 || curLine.All(x => String.IsNullOrEmpty(x) || String.IsNullOrEmpty(x.Trim()))))
continue;
splitLines.Add(curLine);
}
catch (MalformedLineException mfle)
{
// do something with errors here.
}
}
}
return splitLines;
}