Lumenworks快速CsvReader - 由于引号字符,读取制表符分隔文件时出现异常错误

6
我正在使用Lumenworks快速CsvReader,在读取Kelley Blue Book文件时发生了异常错误: “CSV在记录'1281'的字段'5处于位置'1169'附近似乎已损坏” 该文件是使用制表符分隔的。 我发现其中使用了双引号,但我不知道如何转义它并恢复正常,因为它是制表符分隔的数据。
--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设置,但都没有成功。你用的是什么设置可以正常工作?对于逗号分隔文件,我没有遇到太多麻烦。


你得到了什么错误? - Tim Schmelter
它说:“CSV 文件在记录 '1281' 的字段 '5' 位置 '1169' 附近似乎已经损坏。” - fletchsod
1个回答

12

StreamReader 后面缺少一个闭合括号:

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]);
    }
}

我已经使用您上面提供的代码进行了测试(将强制制表符作为文件分隔符),并且测试成功。 输出结果如下:
Column 1: 12345
Column 2: 2013
Column 3: RAV4
Column 4: Sport
Column 5: Sport Utility
Column 6: 4D
Column 7: 2

根据您的评论和提供的文本文件,更新如下:
这个csv读取器可以处理由无效或损坏数据引起的FillError和ParseError异常。因此,您可以处理它们以获取更多信息并进行日志记录。
例如:
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;
    }
}

您需要监听此事件:

csvReader.MissingFieldAction = MissingFieldAction.ParseError;
csvReader.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
csvReader.ParseError += csv_ParseError;

我认识到,在处理类似 RAV4 "Sport" Sport Utility 4D 的数据时,使用双引号 " 作为引用字符不能正常工作。因为该字段本身包含引用字符。所以不需要使用任何引用字符,因为没有字段被引用。在构造函数中不提供引用字符,或将其设置为 '\0'。这样就可以没有问题地运行:

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);
    }
}

你使用的是哪个版本的Lumenworks?我正在使用v3.8.0。很抱歉,我无法附上文本文件以供任何人测试是否会出现错误。 - fletchsod
我也是。为什么你不能把文件上传到某个地方呢?你可以在这里或者你的问题中粘贴链接。 - Tim Schmelter
太棒了!!!它运行得非常好!!我从未听说过使用\0。很高兴学到了这个知识点。我熟悉csv_ParseError()函数并将其用作委托。:-)非常感谢您的帮助!!!! - fletchsod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接