C# 从程序的多个实例将文本写入文件

C# 从程序的多个实例将文本写入文件,c#,file-io,io,C#,File Io,Io,当我将信息写入文件并且程序的多个副本正在运行时,我得到以下错误: 进程无法访问文件“C:\logs\log.txt”,因为另一个进程正在使用该文件 代码是: // create a writer and open the file TextWriter tw2 = File.AppendText(@"C:\logs\log.txt"); // write a line of text to the file tw2.WriteLine(Environment.NewLine); tw2.Wri

当我将信息写入文件并且程序的多个副本正在运行时,我得到以下错误:

进程无法访问文件“C:\logs\log.txt”,因为另一个进程正在使用该文件

代码是:

// create a writer and open the file
TextWriter tw2 = File.AppendText(@"C:\logs\log.txt");

// write a line of text to the file
tw2.WriteLine(Environment.NewLine);
tw2.WriteLine(DateTime.Now + " " + "IN INFOSERVCALLER");
tw2.Flush();

如何正确操作?

除了刷新,还必须
关闭()
文件

此外,如果另一个实例同时写入该文件,则无法访问它(直到另一个程序调用
Close()

关闭writer的当前实例并释放与该writer关联的所有系统资源


在这种情况下,“系统资源”指的是在关闭之前一直处于锁定状态的文件。

每次使用text writer打开文件时,都需要关闭该文件

所以每次手术后使用

// create a writer and open the file
TextWriter tw2 = File.AppendText(@"C:\logs\log.txt");

// write a line of text to the file
tw2.WriteLine(Environment.NewLine);
tw2.WriteLine(DateTime.Now + " " + "IN INFOSERVCALLER");
tw2.Flush();
tw2.Close(); 

之后,再次尝试写下不会进一步产生任何问题的代码。

始终使用语句将此类代码封装在

using(TextWriter tw2 = File.AppendText(@"C:\logs\log.txt"))
{
    tw2.WriteLine(Environment.NewLine); 
    tw2.WriteLine(DateTime.Now + " " + "IN INFOSERVCALLER"); 
    //tw2.Flush();  // No need to flush because close alway flush.
}
using
语句在块的末尾调用tw2.Close() 如果在块内出现异常,也应如此。


现在,如果应用程序的其他实例由于某种原因失败,文件将不再被锁定

请使用类同步多个进程对日志文件的访问。请在打开文件之前调用,在关闭文件之后调用(刷新是不够的,您必须关闭文件或使用关键字将其包装,如其他答案所述)写入完成后。互斥体名称应以前缀“Global”开头.

首先尝试检查文件是否正在使用,请参见以下答案@BaliC:首先检查文件是否已锁定的唯一问题是,在您检查文件和打开文件写入文件之间,文件仍可能被锁定。最好只尝试写入文件并捕获异常(如果发生)。然后稍后重试。刷新为n此处不需要,因为隐式关闭也会刷新流。“关闭”和“使用”都不会阻止异常发生,它只会降低异常发生的概率。仍有可能多个程序实例会尝试同时打开日志文件。对文件的访问必须与相应的同步同步Mutex等基本体。@Ňuf异常将发生,但使用块确保正确关闭文件,然后其他进程可以使用该文件而不被锁定(至于flush,您和ShellShock是对的,复制粘贴:))Steve:问题是“如何以正确的方式进行?”。当程序仍然抛出异常而不是写入文件时,这不是正确的方法。即使没有“using”语句,文件也将正确关闭,唯一的区别是“using”将立即关闭文件,而没有“using”语句,文件将在稍后的desctuctor中关闭(很久)。