关于C#:Lumenworks Fast Csv Reader-由于引号引起的读取标签分隔文件的异常错误

Lumenworks Fast CsvReader - Exception error reading tab delimit file due to quote character

我正在使用Lumenworks Fast CsvReader,读取Kelley Blue Book的文件时发生异常错误:

The CSV appears to be corrupt near record '1281' field '5 at position '1169'

该文件用制表符分隔。 在这里,我发现使用了双引号,但我看不到如何对其进行转义并正常恢复,因为它是制表符分隔的数据。

1
2
3
4
5
6
7
--Characters in Text File--
12345    2013    RAV4"Sport" Sport Utility 4D    2

--Source Code--
using(CsvReader csvReader = new CsvReader(new StreamReader(filePath), false, '\\t', '"', '"', '#', LumenWorks.Framework.IO.Csv.ValueTrimmingOptions.QuotedOnly))
{
}

我没有运气尝试了许多不同的CsvReader设置。 您使用什么效果很好? 我用逗号分隔的文件没有那么多麻烦。


StreamReader后面有一个mssing右括号:

1
2
3
4
5
6
7
8
9
using (CsvReader csvReader = new CsvReader(new StreamReader(filePath), false, '\\t', '"', '"', '#', LumenWorks.Framework.IO.Csv.ValueTrimmingOptions.All))
{
    int fieldCount = csvReader.FieldCount;
    while (csvReader.ReadNextRecord())
    {
        for (int i = 0; i < fieldCount; i++)
            Console.WriteLine("Column {0}: {1}", i + 1, csvReader[i]);
    }
}

我已经用您上面的行(在文件中将制表符作为分隔符)进行了测试,并且可以正常工作。

输出为:

1
2
3
4
5
6
7
Column 1: 12345
Column 2: 2013
Column 3: RAV4
Column 4: Sport
Column 5: Sport Utility
Column 6: 4D
Column 7: 2

根据您的评论和提供的文本文件进行更新:

此csv阅读器可处理无效或损坏的数据引发的FillErrorParseError异常。 因此,您可以处理它们以获得更多信息并用于记录目的。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void csv_ParseError(object sender, ParseErrorEventArgs e)
{
    // if the error is that a field is missing, then skip to next line
    if (e.Error is MissingFieldCsvException)
    {
        //Log.Write(e.Error,"--MISSING FIELD ERROR OCCURRED!" + Environment.NewLine);
        e.Action = ParseErrorAction.AdvanceToNextLine;
    }
    else if (e.Error is MalformedCsvException)
    {
        //Log.Write(e.Error,"--MALFORMED CSV ERROR OCCURRED!" + Environment.NewLine);
        e.Action = ParseErrorAction.AdvanceToNextLine;
    }
    else
    {
        //Log.Write(e.Error,"--UNKNOWN PARSE ERROR OCCURRED!" + Environment.NewLine);
        e.Action = ParseErrorAction.AdvanceToNextLine;
    }
}

您需要收听此事件:

1
2
3
csvReader.MissingFieldAction = MissingFieldAction.ParseError;
csvReader.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
csvReader.ParseError += csv_ParseError;

我已经认识到在文本文件中使用"作为引号是不起作用的,因为某些字段包含诸如RAV4"Sport" Sport Utility 4D之类的数据。 因此,字段本身包含引号字符。 相反,您根本不需要一个,因为没有引用任何字段。 因此,请勿在构造函数中提供一个或将其设置为'\\0'。 这样就可以毫无问题地运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using(var rd  = new StreamReader(filePath))
using (var csvReader = new CsvReader(rd, false, '\\t', '\\0', '\\0', '#', ValueTrimmingOptions.All))
{
    csvReader.MissingFieldAction = MissingFieldAction.ParseError;
    csvReader.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
    csvReader.ParseError += csv_ParseError;
    csvReader.SkipEmptyLines = true;
    int fieldCount = csvReader.FieldCount;
    while (csvReader.ReadNextRecord())
    {
       var fields = new List<string>();
        for (int i = 0; i < fieldCount; i++)
        {
            fields.Add(csvReader[i]);
        }
        lines.Add(fields);
    }
}