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

C# System.IO异常:文件被其他进程占用的排查求助

问题解决:日志文件被占用导致无法追加写入

问题场景

本地调试Excel文件上传功能时,向日志文件追加数据触发如下异常:

The process cannot access the file'C:\Webconfigfiles\Upload\Save\Log_20230706050233.txt' because it is being used by another process.

已有部分日志成功写入,但后续调用日志方法追加时全部报错,重启本地IIS应用池后问题仍存在。当前日志代码已使用using语句尝试释放资源。

现有日志代码

public Logger(string savePath)
{
    filePath = savePath + @"Log_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".txt";
    using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Create)))
    {
        writer.WriteLine("                                                             ");
        writer.WriteLine("-------------------------------------------------------------");
        writer.WriteLine(DateTime.Now.ToString());
        writer.WriteLine("-------------------------------------------------------------");
        writer.Close();
        //logFileStream.Close();
    }

}
public void WriteToLogFile(string Table, string Row, string refTable)
{
    using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Append)))
    {
        //logFileStream = new FileStream(filePath, FileMode.Append);
        //logStreamWriter = new StreamWriter(logFileStream);
        writer.WriteLine("{0} table - Column value for {2} in row {1} of {0} table does not exist in {2} table", Table, Row, refTable);
        writer.Close();
        writer.Close();
    }
}
public void WriteToLogFileWithAppError(string Table, string Row, string Error)
{
    using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Append)))
    {
        writer.WriteLine("[{0} :] {1} table - {1} in row {2} with Error Message: {3}", DateTime.Now, Table, Row, Error);
        writer.Close();
        writer.Close();
    }

}
public void WriteToLogFileWithGeneralError(string Error)
{
    using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Append)))
    {
        writer.WriteLine("");
        writer.WriteLine("[{0} :] Error Message: {1}", DateTime.Now, Error);
        writer.Close();
        writer.Close();
    }
}
public void WriteToLogFile(string msg)
{
    using (var writer = new StreamWriter(new FileStream(filePath, FileMode.Append)))
    {
        writer.WriteLine("");
        writer.WriteLine("{0}", msg);
        writer.Close();
        writer.Close();
    }
}

问题分析

  1. FileStream未设置共享模式:默认FileStream会独占文件,即便using释放资源,操作系统可能未及时释放文件句柄,后续调用打开时会触发占用异常。需显式指定FileShare.ReadWrite允许自身后续调用或其他进程访问文件。
  2. 重复调用writer.Close():using语句会自动执行Dispose(),而StreamWriter.Dispose()会自动关闭流,重复手动调用Close()可能引发资源释放异常。
  3. 文件名时间格式问题:构造函数用hh(12小时制)生成文件名,若上午、下午同一时间段运行程序,会生成重复文件名,导致文件被占用。

修复后的代码

public Logger(string savePath)
{
    // 改用HH(24小时制)避免文件名重复
    filePath = savePath + @"Log_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
    // 显式设置共享模式,允许后续读写操作
    using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
    using (var writer = new StreamWriter(fs))
    {
        writer.WriteLine("                                                             ");
        writer.WriteLine("-------------------------------------------------------------");
        writer.WriteLine(DateTime.Now.ToString());
        writer.WriteLine("-------------------------------------------------------------");
        // 无需手动调用Close,using会自动完成资源释放
    }
}

public void WriteToLogFile(string Table, string Row, string refTable)
{
    using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
    using (var writer = new StreamWriter(fs))
    {
        writer.WriteLine("{0} table - Column value for {2} in row {1} of {0} table does not exist in {2} table", Table, Row, refTable);
    }
}

public void WriteToLogFileWithAppError(string Table, string Row, string Error)
{
    using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
    using (var writer = new StreamWriter(fs))
    {
        writer.WriteLine("[{0} :] {1} table - {1} in row {2} with Error Message: {3}", DateTime.Now, Table, Row, Error);
    }
}

public void WriteToLogFileWithGeneralError(string Error)
{
    using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
    using (var writer = new StreamWriter(fs))
    {
        writer.WriteLine("");
        writer.WriteLine("[{0} :] Error Message: {1}", DateTime.Now, Error);
    }
}

public void WriteToLogFile(string msg)
{
    using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
    using (var writer = new StreamWriter(fs))
    {
        writer.WriteLine("");
        writer.WriteLine("{0}", msg);
    }
}

额外建议

  • 若应用处于多线程环境,建议添加锁机制保证日志写入的原子性,避免多线程同时写入导致日志内容错乱。
  • 优先使用成熟的日志框架(如NLog、Serilog),这类框架已封装好文件锁、资源释放等细节,能大幅减少手动实现的bug。

内容的提问来源于stack exchange,提问作者Akbar Shaik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:35:43