Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read from csv to object[] C#

Tags:

c#

csv

linq

I am trying to read from a .csv file to an object array.

There are other solutions here that give solutions for lists but I cannot seem to make it work for me.

Object definition:

public class DTOClass
{
    //declare data members
    [DataMember]
    public DateTime Date { get; set; }
    [DataMember]
    public string stock_symbol { get; set; }
    [DataMember]
    public double stock_price_open { get; set; }
    [DataMember]
    public double stock_price_close { get; set; }
    [DataMember]
    public double stock_price_low { get; set; }
    [DataMember]
    public double stock_price_high { get; set; }
    [DataMember]
    public double stock_price_adj_close { get; set; }
    [DataMember]
    public long stock_volume { get; set; }
    [DataMember]
    public string stock_exchange { get; set; }
}

Instance declaration:

private DTOClass[] _dTOs;

Filter method:

private List<DTOClass> FromCsv(string csvLine, List<DTOClass> rest)
{
    DataTable _dt = new DataTable();

    string[] values = csvLine.Split(',');

    int j = _dt.Rows.Count;
    for (int i = 0; i < j; i++)
    {
        DTOClass dto = new DTOClass();

        dto.Date = Convert.ToDateTime(values[0]);
        dto.stock_symbol = Convert.ToString(values[1]);
        dto.stock_price_open = Convert.ToDouble(values[2]);
        dto.stock_price_close = Convert.ToDouble(values[3]);
        dto.stock_price_low = Convert.ToDouble(values[4]);
        dto.stock_price_high = Convert.ToDouble(values[5]);
        dto.stock_price_adj_close = Convert.ToDouble(values[6]);
        dto.stock_volume = Convert.ToInt64(values[7]);
        dto.stock_exchange = Convert.ToString(values[8]);

        rest.Add(dto);
    }

    return rest;
}

Calling filter:

DTO = File.OpenText(Filename).ReadLine().Select(v => FromCsv(v.ToString(), 
_restDto)).ToArray();

I need this to return to an object array because it then goes into a CollectionView on a datagrid.

But I keep getting this error:

"Cannot implicitly convert type 'System.Collections.Generic.List[]' to 'MBM.Services.DTOClass[]'"

I know that I'm obviously returning a list of a list, but I've tried other methods that are offered and I'm simply stumped.

I've also tried this:

private static DataTable GetDataTableFromCSVFile(string csv_file_path)
{
    DataTable csvData = new DataTable();

    try
    {
        using (TextFieldParser csvReader = new TextFieldParser(csv_file_path))
        {
            csvReader.SetDelimiters(new string[] { "," });
            //csvReader.HasFieldsEnclosedInQuotes = true;
            string[] colFields = csvReader.ReadFields();

            foreach (string column in colFields)
            {
                DataColumn datecolumn = new DataColumn(column);
                datecolumn.AllowDBNull = true;
                csvData.Columns.Add(datecolumn);
            }

            while (!csvReader.EndOfData)
            {
                string[] fieldData = csvReader.ReadFields();
                //Making empty value as null
                for (int i = 0; i < fieldData.Length; i++)
                {
                    if (fieldData[i] == "")
                    {
                        fieldData[i] = null;
                    }
                }

                csvData.Rows.Add(fieldData);
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    return csvData;
}

Calling with:

DataTable csvData = GetDataTableFromCSVFile(Filename);

But this doesn't seem to return anything from the file.

Any help is appreciated, thanks.

like image 270
BitShift Avatar asked Feb 14 '26 03:02

BitShift


2 Answers

One simple way will be to split the lines and select them into your new object.

var result = File.ReadAllLines("pathTo.csv")
                .Select(line => line.Split(','))
                .Select(x => new MyObject { 
                    prop1 = x[0],
                    prop2 = x[1],
                    //etc.. 
                })
                .ToArray();
like image 175
Drag and Drop Avatar answered Feb 15 '26 16:02

Drag and Drop


There's no point in recreating the wheel, Id just use CsvHelper, it has support for what you're doing in addition to handling malformed CSV's you can additionally set up mapping like so:

public sealed class MyClassMap : ClassMap<MyClass>
{
    public MyClassMap()
    {
        AutoMap();
        Map( m => m.CreatedDate ).Ignore();
    }
}

Then you can get the object like so:

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>();
like image 21
johnny 5 Avatar answered Feb 15 '26 17:02

johnny 5



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!