我有一个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
并适当地分配每个属性(即日期,开放,高)?
答案 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()
将IEnumerable
与List
对话,以匹配您想要的类型。您可以简单地使用foreach
循环将每个DailyValues
实例添加到列表中,而不是使用Linq。