我正在读一个CSV文件,我基本上试图使用标题来确定文件中值的序号位置,尽管最后一部分给了我一些麻烦.以下是我到目前为止的情况:
private static IEnumerable<Cow> ReadCowStream(Stream source)
{
bool isHeader = true;
var cows = new List<Cow>();
using (var reader = new StreamReader(source))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line != null)
{
var values = line.Split(',');
if (isHeader && values.Contains("Weight") && values.Contains("Age"))
{
isHeader = false;
}
else
{
cows.Add(new Cow(
weight: values[0],
age: values[1]));
}
}
}
}
return animals;
}
Run Code Online (Sandbox Code Playgroud)
示例CSV:
Weight,Age
300,10
319,11
100,1
370,9
Run Code Online (Sandbox Code Playgroud)
在这种情况下,输出将是List<Cow>第一个条目具有值"Weight":"300"和"Age":"10"显然,但是如果"Weight"和"Age"被反转怎么办?然后我会将错误的值分配给错误的变量.
基本上,我想用头确定是否将values[0]进入weight或age等,我想我不能保证这是第一位的CSV我读.
使用像CsvHelper这样的库 ,可以根据标题名称而不是索引来提取值.
private static IEnumerable<Cow> ReadCowStream(Stream source) {
var cows = new List<Cow>();
using (var reader = new StreamReader(source)) {
var csv = new CsvReader(reader);
csv.Read();
csv.ReadHeader();
while (csv.Read()) {
cows.Add(new Cow(weight: csv["Weight"], age: csv["Age"]));
}
}
return cows;
}
Run Code Online (Sandbox Code Playgroud)
所以现在,在读取的CSV中首先出现哪个标头并不重要.
该库允许强类型解析.
如果Cow使用默认构造函数定义并且具有适当类型的属性
public class Cow {
public int Age { get; set; }
public int Weight { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
ReadCowStream 可以简化为
private static IEnumerable<Cow> ReadCowStream(Stream source) {
using (var reader = new StreamReader(source)) {
var csv = new CsvReader(reader);
return csv.GetRecords<Cow>().ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
CSV阅读器将解析行,创建实例并通过将标题与属性名称匹配来分配值.