将CSV读取到对象列表

时间:2014-11-06 22:19:42

标签: c# csv

我有一个CSV文件,其中包含各种数据列表(日期时间,小数)。来自CSV的示例行:

Date,Open,High,Low,Close,Volume,Adj Close  //I need to skip this first line as well
2012-11-01,77.60,78.12,77.37,78.05,186200,78.05

我有一个创建的对象列表,我想要读取每一行。对象的构造函数如下所示,每个CSV行的每个字段都在此处使用和分配。

    public DailyValues(DateTime date, decimal open, decimal high, decimal low,
        decimal close, decimal volume, decimal adjClose)
        : this()
    {
        Date = date;
        Open = open;
        High = high;
        Low = low;
        Close = close;
        Volume = volume;
        AdjClose = adjClose;
    }

    List<DailyValues> values = new List<DailyValues>();

是否有一种简单的方法可以将CSV的每一行读入我的列表values并适当地分配每个属性(即日期,开放,高)?

1 个答案:

答案 0 :(得分:65)

为什么不明确解析这些?您的房产数量有限,因此并不是很困难。我没有使用需要很多参数的构造函数,而是使用了一个静态方法,它返回一个新的DailyValues实例,因为它是返回类型。这类似于DateTime.FromBinary等。

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace CsvDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<DailyValues> values = File.ReadAllLines("C:\\Users\\Josh\\Sample.csv")
                                           .Skip(1)
                                           .Select(v => DailyValues.FromCsv(v))
                                           .ToList();
        }
    }

    class DailyValues
    {
        DateTime Date;
        decimal Open;
        decimal High;
        decimal Low;
        decimal Close;
        decimal Volume;
        decimal AdjClose;

        public static DailyValues FromCsv(string csvLine)
        {
            string[] values = csvLine.Split(',');
            DailyValues dailyValues = new DailyValues();
            dailyValues.Date = Convert.ToDateTime(values[0]);
            dailyValues.Open = Convert.ToDecimal(values[1]);
            dailyValues.High = Convert.ToDecimal(values[2]);
            dailyValues.Low = Convert.ToDecimal(values[3]);
            dailyValues.Close = Convert.ToDecimal(values[4]);
            dailyValues.Volume = Convert.ToDecimal(values[5]);
            dailyValues.AdjClose = Convert.ToDecimal(values[6]);
            return dailyValues;
        }
    }
}

当然,您仍然可以添加默认构造函数,并且您将需要在解析失败时添加异常处理(您也可以使用TryParse)。

  • File.ReadAllLines将CSV文件中的所有行读取为字符串数组。
  • .Skip(1)会跳过标题行。
  • .Select(v => DailyValues.FromCsv(v))使用Linq选择每一行,并使用DailyValues方法创建新的FromCsv实例。这会创建System.Collections.Generic.IEnumerable<CsvDemo.DailyValues>类型。
  • 最后,.ToList()IEnumerableList对话,以匹配您想要的类型。

您可以简单地使用foreach循环将每个DailyValues实例添加到列表中,而不是使用Linq。