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

C#使用File.ReadLines读取文件后被锁定 无法通过StreamWriter写入

问题原因
  • File.ReadLines 返回的是延迟求值的IEnumerable<string>类型,并不会在调用时立刻读取所有内容到内存、释放文件句柄,只有当你遍历枚举该返回值的时候才会实际打开文件读取行数据
  • 你将该延迟枚举对象存储为全局变量,后续saveBtn_Click中调用lines.ElementAt(0)时会再次触发枚举、重新打开文件读取内容,和当前要执行的写入操作争抢文件锁,导致报错
  • 未做托管资源的可靠释放,StreamWriter未使用using语法包裹,若写入过程中出现异常未执行Close(),也会导致文件锁长期被占用
解决步骤
  1. 读取文件时立刻将所有行加载到内存,释放文件锁:将IEnumerable<string>类型的lines改为List<string>,调用File.ReadLines后追加.ToList()立刻完成枚举,或者直接使用File.ReadAllLines方法(该方法会直接返回string[],读取完成立刻释放文件)
  2. 所有IO操作类使用using语句包裹,确保异常场景下也能正常释放资源、解除文件锁
修改后代码示例
// 把全局变量类型改为List<string>
List<String> lines;
private void loadCfg()
{
    string cfgPath = Application.StartupPath + @"\server.cfg";
    // 加ToList()立刻加载所有行到内存,读取完成直接释放文件
    lines = File.ReadLines(cfgPath).ToList();
    foreach (var line in lines)
    {
        if (line.Contains("Port"))
        {
            portTxtBox.Text = extractValue(line);
        }
        if (line.Contains("Cars"))
        {
            maxCarsCombo.Text = extractValue(line);
        }
        if (line.Contains("MaxPlayers"))
        {
            maxPlayerCombo.Text = extractValue(line);
        }
     }
}

private void saveBtn_Click(object sender, EventArgs e)
{
    string cfgPath = Application.StartupPath + @"\server.cfg";
    // 用using包裹StreamWriter,用完自动释放资源,不需要手动调用Close
    using (StreamWriter sw = new StreamWriter(cfgPath, false))
    {
        sw.WriteLine(lines.ElementAt(0));
    }
}
补充说明

如果配置文件体积很小,也可以直接用File.ReadAllLines替换File.ReadLines,效果和加.ToList()完全一致:

lines = File.ReadAllLines(cfgPath).ToList();

内容的提问来源于stack exchange,提问作者Smoking Diesel GR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 12:15:04