C# 当一行中的列太多时,是否会出现CSV解析器错误?

C# 当一行中的列太多时,是否会出现CSV解析器错误?,c#,csv,lumenworks,C#,Csv,Lumenworks,我正在使用Lumenworks.Framework.IO.Csv.CsvReader读取Csv文件,并希望检测格式错误的文件。如果一行的列数少于标题,则会抛出LumenWorks.Framework.IO.Csv.MissingFieldCsvException。但是,如果一行的列数大于标题,则在解析该行时,它只会截断该行。是否有任何属性可以设置为使其抛出?还是另一个高效、易于使用并能检测此问题的CSV解析器 我的测试文件看起来像 Field 1,Field 2,Field 3,Field 4

我正在使用
Lumenworks.Framework.IO.Csv.CsvReader
读取Csv文件,并希望检测格式错误的文件。如果一行的列数少于标题,则会抛出
LumenWorks.Framework.IO.Csv.MissingFieldCsvException
。但是,如果一行的列数大于标题,则在解析该行时,它只会截断该行。是否有任何属性可以设置为使其抛出?还是另一个高效、易于使用并能检测此问题的CSV解析器

我的测试文件看起来像

Field 1,Field 2,Field 3,Field 4
This,data,looks,ok
But,this,has,too,many,fields
[Test, ExpectedException(typeof(MalformedCsvException))]
public void Row_cannot_have_more_fields_than_the_header()
{
    using (var stream = File.OpenText("MoreColumnsThanHeader.csv"))
        new CsvParser().ReadCsv(stream);
}
我的集成测试(NUnit)看起来像

Field 1,Field 2,Field 3,Field 4
This,data,looks,ok
But,this,has,too,many,fields
[Test, ExpectedException(typeof(MalformedCsvException))]
public void Row_cannot_have_more_fields_than_the_header()
{
    using (var stream = File.OpenText("MoreColumnsThanHeader.csv"))
        new CsvParser().ReadCsv(stream);
}
和我的代码来读取数据

public DataSubmission ReadCsv(StreamReader streamReader)
{
    var data = new DataSubmission();
    using (var reader = new CsvReader(streamReader, true))
    {
        var items = new List<Row>();
        var fieldCount = reader.FieldCount; //this is 4 in the test
        var headers = reader.GetFieldHeaders();
        while (reader.ReadNextRecord()) //reader has a size 4 array for the 6 item row
            items.Add(ReadRow(fieldCount, headers, reader));
        data.Items = items;
    }
    return data;
}

private static Row ReadRow(int fieldCount, IList<string> headers, CsvReader reader)
{
    var item = new Row();
    var fields = new List<Field>();
    for (var index = 0; index < fieldCount; index++)
        fields.Add(ReadField(headers, reader, index));
    item.Fields = fields;
    return item;
}

private static Field ReadField(IList<string> headers, CsvReader reader, int index)
{
    return new Field {FieldName = headers[index], FieldValue = NullifyEmptyString(reader, index)};
}

private static string NullifyEmptyString(CsvReader reader, int index)
{
    return string.IsNullOrWhiteSpace(reader[index]) ? null : reader[index];
}
public DataSubmission ReadCsv(StreamReader-StreamReader)
{
var data=新数据子任务();
使用(var读取器=新CsvReader(streamReader,true))
{
var items=新列表();
var fieldCount=reader.fieldCount;//这是测试中的4
var headers=reader.GetFieldHeaders();
while(reader.ReadNextRecord())//读卡器的6项行有一个大小为4的数组
添加(ReadRow(fieldCount,headers,reader));
数据项=项目;
}
返回数据;
}
私有静态行ReadRow(int fieldCount、IList头、CsvReader读卡器)
{
var item=新行();
变量字段=新列表();
对于(变量索引=0;索引<字段计数;索引++)
Add(ReadField(headers、reader、index));
项目字段=字段;
退货项目;
}
私有静态字段ReadField(IList头、CsvReader读卡器、int索引)
{
返回新字段{FieldName=headers[index],FieldValue=NullifyEmptyString(reader,index)};
}
私有静态字符串NullifyEmptyString(CsvReader读取器,int索引)
{
返回字符串.IsNullOrWhiteSpace(reader[index])?null:reader[index];
}

编辑:创建此问题后,我已将CSV解析器更改为使用。它易于使用,即使在处理大文件时也表现良好,并且比Lumenworks提供的功能更强大。在处理带引号的字符串中的换行符时,我遇到了Lumenworks解析器的问题。Microsoft解析器可以很好地处理这个问题。

在ReadRow中获取FieldCount,并对照从标题行传入的FieldCount进行检查。如果更大,则抛出异常。

尝试使用Mike Stall提供的csv阅读器()


如果在
DataTable.New
中的任何
Read
方法中设置了
allowMismatch=false
,那么如果给定行中的列数不等于预期的列数,则会出现这种情况。

我采取的方法是使用File.ReadAllLines()然后分别为每行旋转一个CsvReader,并将列计数与标题行的列计数进行比较。如果有任何记录带有额外的逗号,则列计数将更高。大概是这样的:

var rawRecords = File.ReadAllLines(dataFileName);
foreach (string rawRecord in rawRecords)
{
    using (CsvReader csvRawRecord = new CsvReader(new StringReader(rawRecord), false))
    {
        if (csvRawRecord.FieldCount != fileColumnCount)
        {
            return false;
        }
    }
}

不幸的是,这不起作用
reader.FieldCount
即使对于6项行也是4。谢谢,我来看看这个。谢谢,这个看起来可以工作,但是对于大文件可能会很慢。我读到的最大文件有几十万行长,所以性能很重要。自从创建这个问题以来,我实际上已经切换到了另一个CSV解析器,所以我将更新这个问题,这样说。我也这么想,但我在有超过100K条记录的文件上使用了这个解析器,并且对它的速度感到惊讶。