2

Pretty new to C#. Trying to iteratively write to a .txt file and I tried to use this to implement the solution:

Create a .txt file if doesn't exist, and if it does append a new line

I have it written as such:

  var path = @"C:\Test\test.txt";

  try
  {
    if (!File.Exists(path))
    {
      File.Create(path);
      TextWriter tw = new StreamWriter(path);
      tw.WriteLine(message);
      tw.Close();
    }
    else if (File.Exists(path))
    {
      using (var tw = new StreamWriter(path, true))
      {
        tw.WriteLine(message);
        tw.Close();
      }
    }
  }
  catch (Exception e)
  {
    Console.WriteLine(e);
    throw;
  }
}

Whether or not the file exists, it generates the same error:

"System.IO.IOException: The process cannot access the file 'C:\Test\test.txt' because it is being used by another process"

What am I doing wrong this time?

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
cjones
  • 8,384
  • 17
  • 81
  • 175
  • 1
    `System.IO.File.AppendAllText()` is pretty useful for simple tasks. And you don't have to care about unlocking the file. – Jens Feb 26 '19 at 22:09
  • 2
    `File.Create` opens the file. You never closed it, so it will stay open until the garbage collector runs. – Ben Voigt Feb 26 '19 at 22:09
  • 2
    `File.Create(path); TextWriter tw = new StreamWriter(path);` Both open files for writing. Either use the `stream` returned from `File.Create` or just supply a path to `StreamWriter` – spender Feb 26 '19 at 22:10
  • i believe you are running multipe instances of your program probably OR multiple threads are calling this code somehow. You will have to check if the same issue reproduces if you copy this to smaller console application with only the code in this example. – Manoj Choudhari Feb 26 '19 at 22:11

1 Answers1

7

File.Create(path); opens the file and leaves it opened. When you do TextWriter tw = new StreamWriter(path); you are trying to access the file which is being used by the process which created the file (the code line above).

You should do something like this:

if (!File.Exists(path))
{
    using (var stream = File.Create(path))
    {
        using (TextWriter tw = new StreamWriter(stream))
        {
            tw.WriteLine("abc");
        }
    }
}
Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
  • 2
    Alternatively, combine both with `File.CreateText` and you get a stream writer right out the door. Alternatively alternatively, `File.AppendText` also gives you a stream writer, with the additional tweak that it doesn't overwrite the file if it already exists but instead seeks to the end, which avoids the whole "if exist create else append" and is safer to boot (you avoid a potential race condition). Finally, `Close()` is already called by the writer's `Dispose()`, so it's unecessary here. – Etienne de Martel Feb 26 '19 at 22:22