C# File.AppendAllText导致在程序第二次运行时引发访问异常

C# File.AppendAllText导致在程序第二次运行时引发访问异常,c#,.net,file,logging,msdn,C#,.net,File,Logging,Msdn,每次启动应用程序时,我都会删除并创建一个日志文件,如下所示: if (File.Exists(LogPath)) { File.Delete(LogPath); File.Create(LogPath); } 我用File.AppendAllText这样写: File.AppendAllText(LogPath, logMessage); 我的问题是,当我第二次运行该程序时,上面的调用导致抛出一个异常,表示无法访问该文件 “因为它正被另一个进程使用” 这种方法有什么问题?您需要在

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

if (File.Exists(LogPath))
{
   File.Delete(LogPath);
   File.Create(LogPath);
}
我用
File.AppendAllText
这样写:

File.AppendAllText(LogPath, logMessage);
我的问题是,当我第二次运行该程序时,上面的调用导致抛出一个异常,表示无法访问该文件

“因为它正被另一个进程使用”


这种方法有什么问题?

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

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

   }
}
另一种方法是使用WriteAllText,您不必每次都删除它

File.WriteAllText(LogPath, "contents");  

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

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

   }
}
另一种方法是使用WriteAllText,您不必每次都删除它

File.WriteAllText(LogPath, "contents");  

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

File.Create(LogPath);
根据:

返回值
类型:System.IO.FileStream
提供对路径中指定的文件的读/写访问权限的文件流

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

下面介绍如何编写这行代码,以下两种备选方案之一都可以:

File.Create(LogPath).Dispose();
using (File.Create(LogPath)) { }
发生的情况是,在程序第二次运行时,文件存在,因此您删除了它,然后重新创建了它,但“重新创建的”部分保持了文件的打开状态,因此,当它在短时间后到达
文件.AppendAllText
方法时,文件仍然打开

注意:如果您始终调用
文件。AppendAllText
您只需将其删除即可,因为
AppendAllText
将创建文件(如果该文件不存在),如下所示:

打开一个文件,将指定的字符串附加到该文件,然后关闭该文件如果文件不存在,此方法将创建一个文件,将指定的字符串写入该文件,然后关闭该文件


(我的重点)

这不是因为
文件。AppendAllText
而是因为这行代码:

File.Create(LogPath);
根据:

返回值
类型:System.IO.FileStream
提供对路径中指定的文件的读/写访问权限的文件流

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

下面介绍如何编写这行代码,以下两种备选方案之一都可以:

File.Create(LogPath).Dispose();
using (File.Create(LogPath)) { }
发生的情况是,在程序第二次运行时,文件存在,因此您删除了它,然后重新创建了它,但“重新创建的”部分保持了文件的打开状态,因此,当它在短时间后到达
文件.AppendAllText
方法时,文件仍然打开

注意:如果您始终调用
文件。AppendAllText
您只需将其删除即可,因为
AppendAllText
将创建文件(如果该文件不存在),如下所示:

打开一个文件,将指定的字符串附加到该文件,然后关闭该文件如果文件不存在,此方法将创建一个文件,将指定的字符串写入该文件,然后关闭该文件


(我的重点)

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

注意:

File.Create()。删除它并
文件。如果它不存在,AppendAllText将创建一个新文件

注意:
File.Create()

// 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);
如果文件存在,
writealText
将清除该文件并写入
logMessage
;如果文件不存在,
writealText
将创建它并写入
logMessage

你可能是说

// 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);

如果文件存在,
writealText
将清除该文件并写入
logMessage
;如果文件不存在,
writealText
将创建它并写入
logMessage

两个程序实例同时运行?这是影响LogPath指定的文件的唯一代码吗?我本以为
File.Delete(LogPath)会出错甚至在进入
文件.AppendAllText(LogPath,logMessage)之前。两个程序实例同时运行?这是影响LogPath指定的文件的唯一代码吗?我本以为
File.Delete(LogPath)会出错甚至在进入
文件.AppendAllText(LogPath,logMessage)之前。代码第一次工作而不是第二次工作的原因是您没有输入第一次执行
create()
调用的子句。代码第一次工作而不是第二次工作的原因是您没有输入第一次执行
create()
调用的子句。
使用(var handler=File.Create(LogPath)){…}
是一种更好的技术-不要手动关闭
IDisposable
(上下文中的流)
使用(var handler=File.Create(LogPath)){…}
是一种更好的技术-不要手动关闭
IDisposable
(上下文中的流)