我正在使用 FileHelpers 3.3.1 导入CSV数据并在c#应用程序中填充DataTables
。它运作良好,这就是我的称呼方式:
DataTable dt = CsvEngine.CsvToDataTable(fullPath, ',');
问题是某些列值带有填充,例如在值的左侧和/或右侧的空格中,并且这些空格没有被修剪。我的CSV文件很大,并且导入器应用程序的性能很重要,因此我真的想避免事实发生后遍历数据表并修剪每一行的每一列值。
在调用CsvToDataTable()
期间是否可以调用“自动修剪所有列值”?
我知道有一个FieldTrim attribute可以做到这一点,但是我无法将刚性类绑定到我的CSV文件,因为我有很多不同的CSV文件,而且它们都有不同的列名和数据类型。所以这对我来说不是一个实际的选择。似乎将有一种内置的方式来使用trim
之类的通用CSV解析器之一来CsvToDataTable()
。
我最好的选择是什么?
答案 0 :(得分:1)
FileHelpers CsvEngine
类非常有限。这是一个sealed
类,因此您不能轻松地继承或覆盖它。
如果您不介意hacky解决方案,则可以使用以下方法
// Set the internal TrimChars via reflection
public static class FileBaseExtensions
{
public static void SetTrimCharsViaReflection(this FieldBase field, Char [] value)
{
var prop = typeof(FieldBase).GetProperty("TrimChars", BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(field, value);
}
}
CsvOptions options = new CsvOptions("Records", ',', filename);
var engine = new CsvEngine(options);
foreach (var field in engine.Options.Fields)
{
field.SetTrimCharsViaReflection(new char[] { ' ', '\t' });
field.TrimMode = TrimMode.Both;
}
var dataTable = engine.ReadFileAsDT(filename);
但是最好使用标准的FileHelperEngine
并创建自己的CsvClassBuilder
版本(源代码here)来创建映射类。您必须按以下方式更改AddFields
方法:
public override DelimitedFieldBuilder AddField(string fieldName, string fieldType)
{
base.AddField(fieldName, fieldType);
if (base.mFields.Count > 1)
{
base.LastField.FieldOptional = true;
base.LastField.FieldQuoted = true;
base.LastField.QuoteMode = QuoteMode.OptionalForBoth;
base.LastField.QuoteMultiline = MultilineMode.AllowForBoth;
// <New>
base.LastField.TrimMode = TrimMode.Both;
base.LastField.TrimChars = " \t"; // trim spaces and tabs
// </New>
}
return base.LastField;
}
如有必要,您可以从here的CsvToDataTable
源代码中提取CsvEngine
的代码。