【问题标题】:CsvHelper parsing fails for tab delimitted record制表符分隔记录的 CsvHelper 解析失败
【发布时间】:2020-10-30 16:18:25
【问题描述】:

我有一个制表符分隔文件并使用 CsvHelper 在 .Net c# 中解析它 不知何故,它在 1 条记录中失败并抛出 BadData,记录中似乎没有任何问题,我尝试在 excel 中粘贴并使用文本到列,它工作正常。

重现错误的代码

//add CsvHelper nuget package to project
//Create .txt file with below line and pass path of file into function
//copy text from https://gist.github.com/JitenPatoliya/9f9a15eb388c32f46231aa9fa35dd6e3
//Paste into your text file and try this code

private void TestCSvParser(string fullFilePath)
        {
            try
            {
                string ext = Path.GetExtension(fullFilePath);
                using var reader = new StreamReader(fullFilePath);
                using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
                csv.Configuration.BadDataFound = BadDataFound;
                csv.Configuration.DetectColumnCountChanges = true;
                if (ext.IsContains(".txt"))
                {
                    csv.Configuration.Delimiter = "\t";
                }
                while (csv.Read())
                {
                    var fullrow = csv.Context.RawRecord;
                    var record = csv.Parser.Read();
                }
            }
            catch (Exception ex)
            {

            }
        }

private void BadDataFound(ReadingContext ctx)
        {
         //put debug point here
        }

感谢您花时间研究这个问题

【问题讨论】:

标签: c# .net csvhelper


【解决方案1】:

好的,问题是您的某个字段包含",这是一个引号字符。您要么必须对其进行转义,要么忽略文件中的引号。在下面的代码中,我忽略了。此外,如果您将使用Parser.Read,则不应使用csv.Read,因为它在读取之前已经前进到下一条记录。因此,您的代码变为:

private void TestCSvParser(string fullFilePath)
{    
    try
    {
        string ext = Path.GetExtension(fullFilePath);
        using var reader = new StreamReader(fullFilePath);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        csv.Configuration.BadDataFound = BadDataFound;
        csv.Configuration.DetectColumnCountChanges = true;
        if (ext.Contains(".txt"))
        {
            csv.Configuration.Delimiter = "\t";                    
            csv.Configuration.IgnoreQuotes = true;
        }
        string[] record;
        while((record = csv.Parser.Read()) != null)
        {
            var fullrow = csv.Context.RawRecord;
        }                
    }
    catch (Exception ex)
    {

    }
}

【讨论】:

  • 是的,我检查了 IgnoreQuotes 属性,但在这种情况下我需要保留引号,有什么方法可以保留它吗?
  • 似乎使用忽略引号起作用并在解析的文本中保留引号。我正在做更多的测试,并会更新你。感谢您的帮助并指出多个 Read() 跳过了我的记录。
  • @JDev IgnoreQuotes 不会从您的数据中删除引号,它只是不将它们视为“csv 引号”。在 csv 中,您可以在引号之间放置一个字段以转义数据中的换行符和分隔符等内容。例如:"my first field,still first field",second field。请注意,如果我们不使用引号,解析器会找到 3 个字段,而不是 2 个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 2021-01-26
  • 1970-01-01
相关资源
最近更新 更多