You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 15:30:02