CSVHelper BadDataFound 在有效的 csv 中

Jak*_*och 4 c# csv csvhelper

我们的客户开始报告从 CSV 文件导入数据时出现的错误。看到 csv 文件后,我们决定从自定义 CSV 解析器切换到 CSVHelper,但 CSV Helper 无法读取一些有效的 CSV 文件。

\n\n

用户可以将任何 csv 文件加载到我们的应用程序中,因此我们不能使用任何类映射器。我们使用 csv.Parser.Read 来读取 string[] dataRows。我们无法更改此 csv 文件的生成方式,它是由另一家公司生成的,当此文件采用有效格式时,我们无法说服他们更改生成方式。

\n\n

如果我们使用 BadDataFound 处理程序,则 context.RawRecord 为:

\n\n
"1000084;SMRSTOVACI TRUBICE PBF 12,7/6,4 (1/2\\") H;"\n
Run Code Online (Sandbox Code Playgroud)\n\n

csv 文件中的数据行是:

\n\n
1000084;SMRSTOVACI TRUBICE PBF 12,7/6,4 (1/2") H;;;ks;21,59;26,46;21.00;;;8591735015183;8591735015183;Technik;Kabelov\xc3\xbd spojovac\xc3\xad materi\xc3\xa1l;Ozna\xc4\x8dov\xc3\xa1n\xc3\xad, smr\xc5\xa1\xc5\xa5ov\xc3\xa1n\xc3\xad, izolace;Bu\xc5\xbe\xc3\xadrky, smr\xc5\xa1\xc5\xa5ova\xc4\x8dky;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这应该是 RFC 4180 规定的有效 csv 文件。

\n\n

代码是:

\n\n
using (var reader = new StreamReader(filePath, Encoding.Default))\n{\n    using (var csv = new CsvReader(reader))\n    {\n        csv.Read();\n        csv.ReadHeader();\n\n        List<string> badRecord = new List<string>();\n        csv.Configuration.BadDataFound = context => badRecord.Add(context.RawRecord);\n\n        header = csv.Context.HeaderRecord.ToList();\n\n        while (true)\n        {\n            var dataRow = csv.Parser.Read();\n            if (dataRow == null)\n            {\n                break;\n            }\n\n            data.Add(dataRow);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您能帮我配置 CSVHelper 以便能够将此行加载到 string[] 吗?或者你能建议不同的解析来做到这一点吗?

\n\n

谢谢

\n

Dav*_*cht 8

我相信是行中间的引用引起了问题。尝试将配置设置为忽略引号。

using (var reader = new StreamReader(filePath, Encoding.Default))
{
    using (var csv = new CsvReader(reader))
    {
        csv.Configuration.Delimiter = ";";
        csv.Configuration.IgnoreQuotes = true;

        csv.Read();
        csv.ReadHeader();

        List<string> badRecord = new List<string>();
        csv.Configuration.BadDataFound = context => badRecord.Add(context.RawRecord);

        header = csv.Context.HeaderRecord.ToList();

        while (true)
        {
            var dataRow = csv.Parser.Read();
            if (dataRow == null)
            {
                break;
            }

            data.Add(dataRow);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新至版本 27.2.1

using (var reader = new StreamReader(filePath, Encoding.Default))
{
    List<string> badRecord = new List<string>();
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        Delimiter = ";",
        Mode = CsvMode.NoEscape,
        BadDataFound = context => badRecord.Add(context.RawRecord)
    };
    
    using (var csv = new CsvReader(reader, config))
    {
        csv.Read();
        csv.ReadHeader();

        header = csv.Context.Reader.HeaderRecord.ToList();

        while (csv.Parser.Read())
        {           
            data.Add(csv.Parser.Record);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)