项目场景:
需要对某一文件进行同步写入
问题描述
一般的方法:
File.AppendAllText(filePath, $"{curTimeStr}: {recordText}" + Environment.NewLine);
原因分析:
该方法会引起报错:
Information: WriteToFile() catch exception => System.IO.IOException: The process cannot access the file 'C:\Users\e2e\AppData\Local\Temp\ProxyServerTest_20231222-093555' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
异常信息:WriteToFile() 捕获到异常 => System.IO.IOException: 无法访问文件 ‘C:\Users\e2e\AppData\Local\Temp\ProxyServerTest_20231222-093555’,因为它正被另一个进程使用。
在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
这个异常是因为WriteToFile()函数尝试访问的文件’C:\Users\e2e\AppData\Local\Temp\ProxyServerTest_20231222-093555’正在被另一个程序或进程使用。
这种情况通常发生在某个程序或进程打开了文件进行读取或写入时,另一个程序或进程尝试同时访问同一文件。要解决这个问题,你可以尝试以下步骤:
1.关闭可能正在使用该文件的所有程序或进程。
2.检查是否是由防病毒软件或安全软件锁定的文件。如果是,暂时禁用该软件并尝试再次访问文件。
3.使用File.Open()方法配合适当的文件访问模式(读、写、读写)和文件共享模式(无、读、写、读写),以确保正确地访问文件。
4.将WriteToFile()函数包裹在try-catch块中,并处理IOException异常,可以通过在短暂延迟后重试操作或向用户显示错误消息来处理。
解决方案:
在C#中,同时对一个文件进行写入可能会导致数据冲突或损坏,因为多个线程或进程同时修改同一文件可能会产生不可预知的结果。为了安全地在同一文件上进行并发写入,你需要使用适当的同步机制。
private static object fileLock = new object();
public static void SafeWriteToFile(string filePath, string content)
{
lock (fileLock)
{
using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read))
using (StreamWriter writer = new StreamWriter(fs))
{
writer.WriteLine(content);
}
}
}
我们定义了一个静态对象fileLock作为锁对象。
1.SafeWriteToFile方法接受要写入的文件路径和内容作为参数。
2.使用lock语句确保在同一时间只有一个线程可以执行写入操作。
3.使用FileMode.Append模式打开文件,这样每次写入都会添加到文件的末尾,而不是覆盖整个文件。
4.使用StreamWriter来方便地写入文本内容。
请注意,这个示例只保证了在同一应用程序中的线程安全。如果多个进程需要同时写入同一文件,你可能需要使用更复杂的同步机制,如文件锁定、互斥量(Mutex)或者信号量(Semaphore)等。
另外,如果你的应用场景允许,考虑使用日志框架(如NLog、log4net等)或者数据库来处理多源写入,这些工具通常已经内置了处理并发写入的机制。