File.AppendAllText 导致第二次程序运行 时抛出访问异常

File.AppendAllText causes access exception to be thrown when program run for the second time

我有一个日志文件,每次启动我的应用程序时都会删除和创建它,如下所示:

if (File.Exists(LogPath))
{
   File.Delete(LogPath);
   File.Create(LogPath);
}

我正在使用 File.AppendAllText 像这样写:

File.AppendAllText(LogPath, logMessage);

我的问题是,当我第二次 运行 程序时,上述调用导致抛出异常,提示无法访问文件

"because it is being used by another process"

这种方法有什么问题?

您需要在创建后关闭文件以进行进一步处理。

if (File.Exists(LogPath))
{
   File.Delete(LogPath);
   using(var handler = File.Create(LogPath))
   {

   }
}

其他方法可能是使用 WriteAllText,您不需要每次都删除它。

File.WriteAllText(LogPath, "contents");  

这不是因为 File.AppendAllText 而是这行代码:

File.Create(LogPath);

根据the documentation of File.Create(string)

Return Value
Type: System.IO.FileStream
A FileStream that provides read/write access to the file specified in path.

returns 一个打开的 FileStream 对象。您需要处理此对象才能关闭流并释放文件。如果您不这样做,那么此对象将保持文件打开,直到 GC 在以后某个不确定的时间点最终确定该对象。

下面是这行代码的编写方法,以下两种选择之一都可以:

File.Create(LogPath).Dispose();
using (File.Create(LogPath)) { }

发生的事情是你的程序第二次 运行 文件存在,所以你删除它然后重新创建它,但是 "recreated it" 部分保持文件打开,所以当它很短时间到了 File.AppendAllText 方法后,文件仍然打开。

注意:如果你总是调用File.AppendAllText你可以直接删除它,因为AppendAllText会根据 the documentation of File.AppendAllText:

创建文件(如果文件不存在)

Opens a file, appends the specified string to the file, and then closes the file. If the file does not exist, this method creates a file, writes the specified string to the file, then closes the file.

(我的重点)

这是由 File.Create() 引起的。删除它,如果不存在,File.AppendAllText 会创建一个新文件。

注:
File.Create() returns一个FileStream的值,如果不配置,访问时会报错

你,大概,意思是

// clear the file (write an empty text to it) if it exists 
if (File.Exists(LogPath))
{
  File.WriteAllText(LogPath, "");
}    
...    
File.AppendAllText(LogPath, logMessage);

你可以尝试结合一次清除和写入:

File.WriteAllText(LogPath, logMessage);

如果文件存在,WriteAllText会清空并写入logMessage;如果文件不存在,WriteAllText 将创建它并写入 logMessage