My program creates a log file when it starts. The user has the option through settings to "clear the log" which calls a method to delete the log file.
//calls for a YesNo prompt to delete log or not
result = objectMessageBox.ReturnDeleteLogPrompt();
if (result == DialogResult.Yes)
{
//throw prompt
if (File.Exists(objectLog.GetLogLocation()) == true)
{
try
{
//delete the log file
File.Delete(objectLog.GetLogLocation());
//throw balloon tip saying log was cleared
ShowBalloonTip("LogCleared");
}
catch (Exception ee)
{
MessageBox.Show("Error thrown deleting log: " + ee);
System.Windows.Forms.Clipboard.SetText(ee.ToString());
}
}
}
Because I have deleted the log file entirely I need to then recreate it. So I call a method that has this:
try
{
//we create a new log file so it seems that the log has just been cleared
objectLog.CreateLog();
}
catch (Exception ee)
{
MessageBox.Show("Error occured while clearing log:\n" + ee);
}
But when it attempts to recreate the log file it throws an error that says:
"System.IO.IOException: The process cannot access the file '~~' because it is being used by another process."
So it seems that during my call to delete the file it keeps accessing it? Do I need to dispose of something when I call the file.delete
?
I don't know the details, but there are numerous reasons for why a filename isn't immediately available for recreation after deleting an existing file:
Mercurial had this problem on Windows as well. If you executed one command that locked the repository (which was done using temporary files), and then immediately executed another command that either needed to lock, or at least ensure no lock was present, it could fail with the same type of error, the file was in use, even though this was two distinct processes and the first had already exited.
In other words, the timeline was as follows:
Their hack to "fix" this was to simply pick a random filename that wasn't used in the directory, rename the file to that name, and then delete it. This did not solve the problem of the file lingering for a short while, but it did free up the filename and make it available for new files right away.
There already is an accepted answer, but perhaps someone finds this useful (or laugh at it if I missed something obvious again and wasted my time completely)
I had the impression that File.Delete
would either delete the file and then return, or otherwise throw an exception - until I read this thread.
The windows API mentions that by calling DeleteFile
the file is "marked for deletion on close" since it allows calling delete on an open file. After a file is marked for deletion, an attempt to open it will fail as "Access denied". When the last handle for this file is closed, the file is actually deleted.
If windows actually deletes the file before returning from the last CloseHandle
call on the file, in theory this code would guarantee that the file is deleted below the using
block:
using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete))
{
File.Delete(path);
}
The File.Open
would fail if another process currently has the file open.
Note the difference here that File.Delete
even succeeds if a file does not exist (unless the directory does not exist).
Instead of deleting and recreating the same file, can you just clear it out?
Something like this should work for you:
FileStream f = File.Open(@[filename], FileMode.Create);
f.Close();
You could use System.IO.FileInfo.Delete to delete the file, and then System.IO.FileInfo.Refresh() before creating the file again. The Refresh should stop the exception from happening on re-creating the file. Or as nycdan says, use the FileMode.Create enum.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.