/// <summary> /// Construct a new CSV reader off a streamed source /// </summary> /// <param name="source">The stream source. Note that when disposed, the CSV Reader will dispose the stream reader.</param> /// <param name="settings">The CSV settings to use for this reader (Default: CSV)</param> public CSVReader(Stream source, CSVSettings settings = null) { _settings = settings; if (_settings == null) { _settings = CSVSettings.CSV; } _stream = new StreamReader(source, _settings.Encoding); // Do we need to parse headers? if (_settings.HeaderRowIncluded) { var line = _stream.ReadLine(); if (_settings.AllowSepLine) { var newDelimiter = CSV.ParseSepLine(line); if (newDelimiter != null) { // We don't want to change the original settings, since they may be a singleton _settings = _settings.CloneWithNewDelimiter(newDelimiter.Value); line = _stream.ReadLine(); } } Headers = CSV.ParseLine(line, _settings); } else { Headers = _settings.AssumedHeaders; } }
/// <summary> /// Read this file into a data table in memory /// </summary> /// <returns></returns> public DataTable ReadAsDataTable() { var dt = new DataTable(); string[] firstLine = null; // File contains column names - so name each column properly if (Headers == null) { var rawLine = _stream.ReadLine(); firstLine = CSV.ParseLine(rawLine, _settings); var list = new List <string>(); for (var i = 0; i < firstLine.Length; i++) { list.Add($"Column{i}"); } this.Headers = list.ToArray(); } // Add headers var numColumns = Headers.Length; foreach (var t in Headers) { dt.Columns.Add(new DataColumn(t, typeof(string))); } // If we had to read the first line to get dimensions, add it var row_num = 1; if (firstLine != null) { dt.Rows.Add(firstLine); row_num++; } // Start reading through the file foreach (var line in CSV.ParseStream(_stream, _settings)) { // Does this line match the length of the first line? if (line.Length != numColumns) { if (!_settings.IgnoreDimensionErrors) { throw new Exception($"Line #{row_num} contains {line.Length} columns; expected {numColumns}"); } else { // Add as best we can - construct a new line and make it fit var list = new List <string>(); list.AddRange(line); while (list.Count < numColumns) { list.Add(""); } dt.Rows.Add(list.GetRange(0, numColumns).ToArray()); } } else { dt.Rows.Add(line); } // Keep track of where we are in the file row_num++; } // Here's your data table return(dt); }