使用CsvReader TryGetField时如何区分未转义引号与记录结束?
区分CsvReader中TryGetField返回false的两种情况
在使用CsvReader动态解析记录时,遇到未转义引号导致TryGetField返回false时,可以通过以下两种方式区分是记录结束还是数据格式错误:
方式一:检查Parser的状态属性
CsvReader的内部Parser对象提供了IsFieldBad和FieldError属性,专门用于标记字段解析错误:
while (await csvRecordReader.ReadAsync().ConfigureAwait(false)) { var fieldList = new List<string>(); int iterator = 0; bool isBadData = false; string? errorMsg = null; while (true) { if (csvRecordReader.TryGetField(iterator, out string? field)) { fieldList.Add(field); iterator++; } else { // 判断是否是字段解析错误 if (csvRecordReader.Parser.IsFieldBad) { isBadData = true; errorMsg = csvRecordReader.Parser.FieldError; } break; } } if (isBadData) { // 处理数据错误,比如记录错误信息、跳过当前记录等 Console.WriteLine($"解析错误:{errorMsg}"); } else { // 正常处理解析完成的字段列表 Console.WriteLine($"成功解析 {fieldList.Count} 个字段"); } }
方式二:配置全局错误回调
在初始化CsvConfiguration时,通过ReadingExceptionOccurred回调捕获解析错误,标记错误状态:
bool hasParsingError = false; var parserConfig = new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = '|', Mode = CsvMode.RFC4180, Escape = '"', ReadingExceptionOccurred = ex => { hasParsingError = true; // 返回false表示继续解析后续记录,返回true则终止整个解析流程 return false; } }; using var streamRecord = new StringReader(dataToParse); var csvRecordReader = new CsvReader(streamRecord, parserConfig); while (await csvRecordReader.ReadAsync().ConfigureAwait(false)) { hasParsingError = false; var fieldList = new List<string>(); int iterator = 0; while (csvRecordReader.TryGetField(iterator, out string? field)) { fieldList.Add(field); iterator++; } if (hasParsingError) { Console.WriteLine("当前记录存在格式错误"); } else { Console.WriteLine($"记录解析完成,共 {fieldList.Count} 个字段"); } }
注意事项
Parser.FieldError会返回具体的错误描述,比如未闭合引号时会显示"Bad field: Quoted field not closed.",便于定位问题。- 若需要严格校验数据,可在
ReadingExceptionOccurred中返回true,直接终止解析;若需容错处理,返回false即可跳过错误记录继续解析。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

