2

I have the following code:

public WriteToFile(string path, List<string> text)
{
    File.Delete(path);
    using (TextWriter writer = new StreamWriter(path, true))
    {
        foreach(string t in text)
        {
            writer.WriteLine(text);
        }
    }
}

Most of the time it works fine, the file is deleted and then created again with the text inside. However every so often the using statement throws an UnauthorizedAccessException. Any idea why? I have admin rights and the program is run as admin.

shortspider
  • 1,045
  • 15
  • 34
  • 2
    Is the file very large? Perhaps your code is trying to open it while the system is still trying to delete it. Also, using `StreamWriter( path, false )` will overwrite the file, no need to delete beforehand – CDspace Sep 09 '13 at 15:18
  • 3
    why bother to delete it? just overwrite it and you won't have the problem at all – Sayse Sep 09 '13 at 15:19
  • This may be related: http://stackoverflow.com/questions/8821410/system-unauthorizedaccessexception-access-to-the-path-denied – user7116 Sep 09 '13 at 15:28
  • @CDspace File class is synchronous. Does it tell the OS to delete the file and then continue, or wait for the file to be deleted first before moving on? – Serguei Fedorov Sep 09 '13 at 15:33
  • If the file is `ReadOnly` you'll get this exception – Sriram Sakthivel Sep 09 '13 at 15:37
  • Does the file path change? Is it always the same file or same folder? – John Saunders Sep 09 '13 at 15:51
  • @SergueiFedorov After more tests, yes, File.Delete() does block until it finishes, but my main point was to use the append flag with `StreamWriter`. Less points of possible failure, and if it's there, use it rather than doing more work – CDspace Sep 09 '13 at 16:32
  • @CDspace I have updated my code to more accurately show what I am doing. The file consists of lines of text. When rewriting the file there may be more or less lines of text. Does rewriting the file work in the case that there is less lines of text? I didn't think it would which is why I delete and then write. – shortspider Sep 09 '13 at 17:03
  • File.WriteAllLines is the ideal workaround here. – Rotem Sep 09 '13 at 17:05
  • Try to do this manually. Create and close out the stream yourself rather than relying on the the Using to do it for you. It is hard to say what the internal logic is in the Dipose method, so better be sure yourself that your closing the stream (as in create and close the TextWriter yourself rather than through "using") – Serguei Fedorov Sep 09 '13 at 17:08

1 Answers1

3

This is normal, it became undiagnosable because you used File.Delete(). Which is unnecessary, just use the StreamWriter(string) constructor.

This goes wrong because deleting a file doesn't provide a guarantee that the file will actually be deleted. It may be opened by another process. Which has opened the file with delete sharing, programs like virus scanners and file indexers commonly do this. Which makes the Delete() call succeed but the file doesn't disappear until all handles on the file are closed. You got the UnauthorizedAccessException exception because the file didn't get deleted yet.

Get ahead by removing the File.Delete() call. You still need to assume that the StreamReader() constructor can fail. Less often, it is bound to happen sooner or later. You'll get a better exception message. Such are the vagaries of a multi-tasking operating system.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    So this is just something that needs to be guarded against regardless of my code? I get that removing the `Delete` will reduce the number of occurrences of this exception but I should still expect it to occur? That seems very odd to me. – shortspider Sep 10 '13 at 14:19