如何使用CsvHelper类跳转至CSV指定RowId行并读取?
如何用CsvHelper跳转到CSV指定RowId的行并读取后续内容
你需要从包含RowId列的CSV文件中,直接跳转到指定RowId的行(如RowId=230),并从该行开始读取后续记录,以下是基于CsvHelper的实现方案:
现有代码基础
你的CSV结构示例:
RowId,Name 0,Raju 1,Sabu 2,Ravi 3,Lal 4,Babu
当前读取CSV的代码:
CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = true, Delimiter = ",", PrepareHeaderForMatch = args => args.Header.ToUpper(), IgnoreBlankLines = true, IgnoreReferences = true, MissingFieldFound = null, UseNewObjectForNullReferenceMembers = true }; CsvReader csv = new CsvReader(File.OpenText(FileNameWithPath), csvConfiguration); csv.Read(); csv.ReadHeader(); while (csv.Read()) { string d0 = csv.GetField<string>("Name"); var d5 = csv.GetField<int>("Class"); }
解决方案1:逐行定位目标RowId(推荐,内存友好)
这种方式会逐行读取直到找到目标RowId,然后开始处理当前行及后续所有行,适合任意大小的CSV文件:
int targetRowId = 230; using (var fileReader = File.OpenText(FileNameWithPath)) using (var csv = new CsvReader(fileReader, csvConfiguration)) { csv.Read(); csv.ReadHeader(); // 循环跳过行,直到找到目标RowId while (csv.Read()) { var currentRowId = csv.GetField<int>("ROWID"); // 配置中已将表头转大写,使用大写列名更稳妥 if (currentRowId == targetRowId) { // 处理目标行 string name = csv.GetField<string>("NAME"); int classNum = csv.GetField<int>("CLASS"); // 这里添加目标行的业务逻辑 // 继续处理后续所有行 while (csv.Read()) { name = csv.GetField<string>("NAME"); classNum = csv.GetField<int>("CLASS"); // 添加后续行的业务逻辑 } break; // 跳出外层循环,结束查找 } } }
注意事项:
- 由于你的配置中开启了
PrepareHeaderForMatch = args => args.Header.ToUpper(),读取字段时使用大写列名(如ROWID、NAME)可以避免大小写不匹配的问题。 - 这种方法不依赖
RowId与实际行号的连续性,即使CSV中存在缺失的RowId,也能准确找到目标行。
解决方案2:使用LINQ简化代码(适合小文件)
如果CSV文件规模较小(如2000行),可以通过定义模型类配合LINQ实现,代码更简洁:
步骤1:定义CSV对应模型
public class CsvRecord { public int RowId { get; set; } public string Name { get; set; } public int Class { get; set; } }
步骤2:用LINQ筛选并读取
int targetRowId = 230; using (var fileReader = File.OpenText(FileNameWithPath)) using (var csv = new CsvReader(fileReader, csvConfiguration)) { csv.Read(); csv.ReadHeader(); // 跳过所有RowId不等于目标值的记录,从匹配的行开始读取 var targetRecords = csv.GetRecords<CsvRecord>() .SkipWhile(record => record.RowId != targetRowId); foreach (var record in targetRecords) { // 处理记录:record.RowId、record.Name、record.Class } }
注意事项:
GetRecords<T>()会枚举整个CSV文件,直到找到目标行,对于大文件来说内存占用略高,但2000行的规模完全没问题。- 模型类的属性名需要与CSV表头匹配(或通过
[Name]特性指定对应关系),由于你的配置会将表头转大写,也可以将模型属性名设为大写(如ROWID)。
内容的提问来源于stack exchange,提问作者Micheal
相关产品推荐
相关产品推荐

