Toto
Toto

Reputation: 970

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

I have a log file that I delete and create every time my application is launched like so:

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

And I'm writing in it using File.AppendAllText like so:

File.AppendAllText(LogPath, logMessage);

My issue is that when I run the program for the second time, the above call causes an exception to be thrown saying file can't be accessed

"because it is being used by another process"

What is wrong with this approach?

Upvotes: 0

Views: 3764

Answers (4)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186718

You, probably, mean

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

you can try combining clearing and writing in one call:

File.WriteAllText(LogPath, logMessage);

If the file exists, WriteAllText will clear it and write logMessage; if file doesn't exist, WriteAllText will create it and write logMessage.

Upvotes: 0

kgzdev
kgzdev

Reputation: 2885

It's caused by File.Create(). Remove it and File.AppendAllText creates a new file if it doesn't exist.

Note:
File.Create() returns a FileStream value, if you do not dispose it, then it will cause an error when you want to access it.

Upvotes: 4

Ali Baig
Ali Baig

Reputation: 3867

You would need to close the file after you create for further processing.

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

   }
}

Other way could be to use WriteAllText and you won't need to delete it everytime.

File.WriteAllText(LogPath, "contents");  

Upvotes: 0

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391396

This is not because of File.AppendAllText but instead this line of code:

File.Create(LogPath);

As per 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.

It returns an open FileStream object. You need to dispose of this object in order to close the stream and release the file. If you don't then this object will keep the file open until GC finalizes the object at some later indeterminate point in time.

Here's how to write this line of code, either one of the following two alternatives will work:

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

What happened is that the second time your program ran the file exists, so you deleted it and then recreated it, but the "recreated it" part kept the file open, so when it a short time later reached the File.AppendAllText method, the file was still open.

Note: If you always call File.AppendAllText you can simply just delete it, as AppendAllText will create the file if it doesn't already exist, as per 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.

(my emphasis)

Upvotes: 2

Related Questions