C# 使用FileHelpers将动态CSV读取到DataTable

C# 使用FileHelpers将动态CSV读取到DataTable,c#,.net,csv,filehelpers,C#,.net,Csv,Filehelpers,我发现FileHelper非常方便地处理“富”CSV,带有自定义分隔符、带引号的标识符、空项过滤等。 但它似乎主要用于加载具有预先已知格式的文件,以创建强类型对象列表,并使用假定与标题匹配的属性装饰属性 我的目的有点不同: 我想能够加载定制的CSV文件,格式和列数事先不知道,在一个灵活的格式,如DataTable,或某种字符串数组。旁注:我的csv来自流,而不是物理文件 我做了一些尝试,使用了FileHelperEngine中的ReadStreamAsDT等方法(下面是完整的实现),但遇到了一些

我发现FileHelper非常方便地处理“富”CSV,带有自定义分隔符、带引号的标识符、空项过滤等。 但它似乎主要用于加载具有预先已知格式的文件,以创建强类型对象列表,并使用假定与标题匹配的属性装饰属性

我的目的有点不同: 我想能够加载定制的CSV文件,格式和列数事先不知道,在一个灵活的格式,如DataTable,或某种字符串数组。旁注:我的csv来自流,而不是物理文件

我做了一些尝试,使用了
FileHelperEngine
中的
ReadStreamAsDT
等方法(下面是完整的实现),但遇到了一些问题

  • 如果标题包含空格或其他不能出现在C#属性中的字符,则会引发异常“
    字符串“My field”不是有效的.NET标识符”。我的标题可以包含所有类型的字符
  • 它需要单独手动解析标题行
我的实现存在上述问题:

using (var streamReader = new StreamReader(stream, true))
{   
    var cb = new DelimitedClassBuilder("temp", ";")
    {
        IgnoreFirstLines = 0,
        IgnoreEmptyLines = true,
        Delimiter = ";"
    };
    var headerArray = streamReader.ReadLine().Split(';');
    foreach (var header in headerArray)
    {
        cb.AddField(header, typeof(string));
        cb.LastField.FieldQuoted = true;
        cb.LastField.QuoteChar = '"';
    }

    var engineType = cb.CreateRecordClass();
    var engine = new FileHelperEngine(engineType);
    var datatable = engine.ReadStreamAsDT(streamReader);
}
我希望避免导入除FileHelpers之外的另一个CSV包,并且由于我们以后还需要使用相同的逻辑生成一些CSV,因此我希望避免为此编写自己的代码

FileHelpers文档对我使用DataTable帮助不大

我还注意到了类似于
CommonEngine.csvtodatable()
CsvEngine.csvtodatable()
的单行程序方法,但它旨在从物理文件工作


有没有一种方法可以让FileHelper利用一些Is高级功能(安全报价处理、修剪、CSV生成等)?

在我写这个问题时,我刚刚编写了自己的代码,将CSV文件加载到datatable,并提供了我所需的所有功能

然而,除了FileHelpers之外,还有一个库在这个领域做得更好,“CsvHelper”:

(如果需要自定义分隔符等,只需设置分隔符)

或者,如果您愿意,也可以手动执行:
如果您愿意。

您不需要使用任何第三方库将CSV文件读入
数据表
对象-您可以使用OLE-DB直接读取CSV文件:@Dai,它确实需要一个额外的组件,即必须匹配应用程序位的Jet驱动程序。它也不能处理奇怪的CSV,例如那些带有标题或无效行的CSV。我不确定它是否可以处理带有换行符的文本字段,这在csvsThreak@Dai中是允许的,但使用OLE/Jet绝对不是我想要的方式。我想要一个具有可定制行为的“托管”解决方案。
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader))
{
    // Do any configuration to `CsvReader` before creating CsvDataReader.
    using (var dr = new CsvDataReader(csv))
    {        
        var dt = new DataTable();
        dt.Load(dr);
    }
}