【发布时间】:2016-07-21 22:13:51
【问题描述】:
我正在尝试从具有以下结构的 CSV 文件中读取两种类型的记录:
PlaceName,Longitude,Latitude,Elevation
NameString,123.456,56.78,40
Date,Count
1/1/2012,1
2/1/2012,3
3/1/2012,10
4/2/2012,6
我知道这个问题之前已经在
但是当我运行我的实现时,它得到一个CsvMissingFieldException 说Fields 'Date' do not exist in the CSV file。我有两个定义和地图类,一个用于位置,另一个用于计数,它们是:
public class LocationDefinition
{
public string PlaceName { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
public double Elevation { get; set; }
}
public sealed class LocationMap : CsvClassMap<LocationDefinition>
{
public LocationMap()
{
Map(m => m.PlaceName).Name("PlaceName");
Map(m => m.Longitude).Name("Longitude");
Map(m => m.Latitude).Name("Latitude");
Map(m => m.Elevation).Name("Elevation");
}
}
public class CountDefinition
{
public DateTime Date { get; set; }
public int Count { get; set; }
}
public sealed class CountMap : CsvClassMap<CountDefinition>
{
public CountMap()
{
Map(m => m.Date).Name("Date");
Map(m => m.Count).Name("Count");
}
}
我用于读取 csv 文件的代码是:
LocationDefinition Location;
var Counts = new List<CountDefinition>();
using (TextReader fileReader = File.OpenText(@"Path\To\CsvFile"))
using (var csvReader = new CsvReader(fileReader))
{
csvReader.Configuration.RegisterClassMap<LocationMap>();
csvReader.Configuration.RegisterClassMap<CountMap>();
// Only reads a single line of Location data
csvReader.Read();
LocationData = csvReader.GetRecord<LocationDefinition>();
csvReader.Read(); // skip blank line
csvReader.Read(); // skip second header section
// Read count data records
while (csvReader.Read())
{
var tempCount = csvReader.GetRecord<CountDefinition>();
Counts.Add(tempCount);
}
}
在tempCount 行上抛出异常。据我所知,它仍然需要位置记录,但我原以为GetRecord<CountDefinition> 会指定记录类型。我也试过ClearRecordCache 和注销LocationMap 无济于事。
应如何更改此代码以使其读取此结构的 csv 文件?
【问题讨论】:
-
结构是否重复?您可以发布多个结构。 40 年来一直在解析这样的文件,并且可以轻松给出一个很好的解决方案。
-
location部分只出现一次,会在count部分之前(目前只有一条记录),count部分可以有任意条记录。让代码能够处理任意数量的位置记录可能是值得的。
-
我会在出现 CRLF 的地方将文件一分为二。一旦它初始化了 Location def,我就无法放手。