C#使用CSVHelper跳过CSV行至指定词报TextReader已关闭错误如何解决
问题排查与修复方案
错误根因
- 读行逻辑错误:
CsvReader.Read()返回值为布尔类型,仅代表是否成功读取到下一行,不是当前行的内容。你代码中重复调用csv.Read()会导致每次循环跳过2行,且拿布尔值和"Date/Time"对比永远为假,无法正确定位到目标行。 - 资源提前释放:
CsvDataReader的using块被放在了查找目标行的while循环内,dt.Load(dr)执行时会一次性读完所有剩余行,using块退出时CsvDataReader会同步释放底层的TextReader,下一次循环调用csv.Read()时就会触发Cannot read from a closed TextReader异常。 - 边界校验缺失:如果用户在文件选择弹窗点击取消,
OFDReader.FileName为空,后续创建StreamReader会直接报错。
修复后代码
private void cmdLoad_Click(object sender, EventArgs e) { OpenFileDialog OFDReader = new OpenFileDialog() { Filter = "CSV文件|*.csv|所有文件|*.*" }; // 未选择文件直接退出 if (OFDReader.ShowDialog() != DialogResult.OK) { return; } txtbox.Text = OFDReader.FileName; var config = new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = ";", HasHeaderRecord = true, }; using (var reader = new StreamReader(OFDReader.FileName)) using (var csv = new CsvReader(reader, config)) { string targetKeyword = "Date/Time"; bool findTargetHeader = false; // 仅遍历查找目标行,不加载数据 while (csv.Read()) { // 匹配第一列是否包含目标关键词,可根据实际需求调整匹配逻辑 if (csv.GetField<string>(0).Contains(targetKeyword)) { findTargetHeader = true; // 当前行就是表头行,读取表头 csv.ReadHeader(); break; } } // 未找到目标行直接退出 if (!findTargetHeader) { MessageBox.Show("未找到指定表头行"); return; } // 定位到表头后再统一加载所有后续数据 using (var dr = new CsvDataReader(csv)) { var dt = new DataTable(); dt.Load(dr); dataGridView1.DataSource = dt; } } }
内容的提问来源于stack exchange,提问作者xKara
相关产品推荐
相关产品推荐

