我最近为 .NET 编写了一个 CSV parser,I'm claiming is currently the fastest 可作为 nuget 包使用:Sylvan.Data.Csv。
使用这个库来加载DataTable 非常简单。
using var dr = CsvDataReader.Create("data.csv");
var dt = new DataTable();
dt.Load(dr);
假设您的文件是带有标题的标准逗号分隔文件,这就是您所需要的。还有一些选项可以允许读取没有标题的文件,以及使用备用分隔符等。
还可以为 CSV 文件提供自定义架构,以便可以将列视为 string 值以外的其他内容。这将允许 DataTable 列加载更易于使用的值,因为您在访问它们时不必强制它们。
这可以通过提供一个 ICsvSchemaProvider 实现来实现,它公开了一个方法 DbColumn? GetColumn(string? name, int ordinal)。 DbColumn 类型是System.Data.Common 中定义的抽象类型,这意味着如果您实现自己的模式提供程序,您也必须提供它的实现。 DbColumn 类型公开有关列的各种元数据,您可以根据需要选择公开尽可能多的元数据。最重要的元数据是DataType 和AllowDBNull。
一个公开类型信息的非常简单的实现可能如下所示:
class TypedCsvColumn : DbColumn
{
public TypedCsvColumn(Type type, bool allowNull)
{
// if you assign ColumnName here, it will override whatever is in the csv header
this.DataType = type;
this.AllowDBNull = allowNull;
}
}
class TypedCsvSchema : ICsvSchemaProvider
{
List<TypedCsvColumn> columns;
public TypedCsvSchema()
{
this.columns = new List<TypedCsvColumn>();
}
public TypedCsvSchema Add(Type type, bool allowNull = false)
{
this.columns.Add(new TypedCsvColumn(type, allowNull));
return this;
}
DbColumn? ICsvSchemaProvider.GetColumn(string? name, int ordinal)
{
return ordinal < columns.Count ? columns[ordinal] : null;
}
}
要使用此实现,您需要执行以下操作:
var schema = new TypedCsvSchema()
.Add(typeof(int))
.Add(typeof(string))
.Add(typeof(double), true)
.Add(typeof(DateTime))
.Add(typeof(DateTime), true);
var options = new CsvDataReaderOptions
{
Schema = schema
};
using var dr = CsvDataReader.Create("data.csv", options);
...