我有一堆需要读取的CSV文件,除了添加一列外,它们都相似。本质上,旧的CSV格式有7列,而新的CSV格式有8列。一旦读取,新列将被默认/编辑,然后在写出时文件将具有8列-因此将来的读取现在将具有新列。
因此,我正在尝试执行以下CvsHelper示例:Reading Multiple Record Types
除了唯一的区别是文件中的列数-不是标识字段值。
我尝试了CsvParser在它自己的using()中使用文件第一行的单个Read()来确定列数,并认为在随后的using()中CsvReader可以为该类注册特定于计数的ClassMap CsvReader.GetRecords。但是,似乎没有一个属性或方法可以回答解析器遇到的列数。与CsvReader.Read()相同-Read()之后CsvReader.Context.ColumnCount为零。任何想法/指针表示赞赏。
更新
这是我的代码(我知道长名):
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using CsvHelper;
using CsvHelper.Configuration;
namespace TopazDomain.Classes.Extensions
{
public static class FootprintComponentMapFileExtensions
{
public sealed class FootprintComponentReadMapper : ClassMap<FootprintComponentMap>
{
public FootprintComponentReadMapper()
{
Map(m => m.Footprint).Index(0);
Map(m => m.Value).Index(1);
Map(m => m.Component).Index(2);
Map(m => m.Head).Index(3);
Map(m => m.CompR).Index(4);
Map(m => m.Polarized).Index(5);
Map(m => m.Comment).Index(6);
Map(m => m.LibR).ConvertUsing(row =>
{
if (row.TryGetField(7, out string field))
{
return field;
}
else
{
return String.Empty;
}
});
}
}
public sealed class FootprintComponentWriteMapper : ClassMap<FootprintComponentMap>
{
public FootprintComponentWriteMapper()
{
Map(m => m.Footprint).Index(0);
Map(m => m.Value).Index(1);
Map(m => m.Component).Index(2);
Map(m => m.Head).Index(3);
Map(m => m.CompR).Index(4);
Map(m => m.Polarized).Index(5);
Map(m => m.Comment).Index(6);
Map(m => m.LibR).Index(7);
}
}
public static bool ImportFootprintComponentMaps(this FootprintComponentMapFile footprintComponentMapFile,
string filename)
{
bool done = false;
using (var lineReader = new LineReader(filename))
using (var csv = new CsvReader(lineReader, CultureInfo.InvariantCulture))
{
csv.Configuration.RegisterClassMap<FootprintComponentReadMapper>();
footprintComponentMapFile.FootprintComponentMaps = csv.GetRecords<FootprintComponentMap>().ToList();
done = true;
}
return done;
}
public static bool ExportFootprintComponentMaps(this FootprintComponentMapFile footprintComponentMapFile,
string filename)
{
bool done = false;
CsvConfiguration cvsConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture);
cvsConfiguration.HasHeaderRecord = false;
using (var lineWriter = new StreamWriter(filename))
using (var csv = new CsvWriter(lineWriter, cvsConfiguration))
{
csv.Configuration.RegisterClassMap<FootprintComponentWriteMapper>();
csv.WriteRecords(footprintComponentMapFile.FootprintComponentMaps);
done = true;
}
return done;
}
}
}
您可以拥有一个具有8个属性的新对象,并使用ConvertUsing
有条件地映射第8列。
public class OldFoo
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class NewFoo
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class NewFooClassMap : ClassMap<NewFoo>
{
public NewFooClassMap()
{
Map(m => m.Id).Index(0);
Map(m => m.FirstName).Index(1);
Map(m => m.LastName).ConvertUsing(row => {
if(row.TryGetField(2, out string field))
{
return field;
}
else
{
return null;
}
});
}
}
public class Program
{
public static void Main(string[] args)
{
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
writer.WriteLine("1,Bob");
writer.WriteLine("2,Davey");
writer.Flush();
stream.Position = 0;
csv.Configuration.RegisterClassMap<NewFooClassMap>();
csv.Configuration.HasHeaderRecord = false;
var records = csv.GetRecords<NewFoo>().ToList();
}
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
writer.WriteLine("1,Bob,Barker");
writer.WriteLine("2,Davey,Jones");
writer.Flush();
stream.Position = 0;
csv.Configuration.RegisterClassMap<NewFooClassMap>();
csv.Configuration.HasHeaderRecord = false;
var records = csv.GetRecords<NewFoo>().ToList();
}
}
}