Search code examples
c#filedisposetextwriter

When to call File.Dispose()


I am trying to use a text writer to write text to a file in .NET Core. The below code doesn't output anything to the file:

TextWriter writer = File.CreateText(@"...txt");
writer.Write("Hello World");

However, this does:

TextWriter writer = File.CreateText(@"...txt");
writer.Write("Hello World");
writer.Dispose();

Why is that? What does that extra line tell the program to do differently? I don't want to close the TextWriter because it is going to be writing logs, which are running constantly and indefinitely whilst my application is running.

How can I keep it open until the application stops running?

UPDATE

So the reason I want to do this, is I am using an SDK that writes its logs to a TextWriter:

TextWriterLogger(textWriter);
//Creates a logger that writes to a TextWriter. User is responsible for providing an instance of TextWriter that is thread safe.

But if I just enclose this in a using statement, logs won't be written because by the time they are ready to be written, the using statement will have executed and the TextWriter disposed.

Thanks


Solution

  • Dispose calls Flush, which writes the internal bytes stored in a buffer to disk

    Without closing or disposing a file, you are leaving unmanaged resources around and will potentially lock the file, not to mention memory leaks. Instead always use a using statement

    using (TextWriter writer = File.CreateText(@"...txt"))
    {
       writer.Write("Hello World");
    }
    

    However if you want to continually write to the file, you will have to flush it

    FileStream.Flush Method

    Clears buffers for this stream and causes any buffered data to be written to the file.

    TextWriter writer = File.CreateText(@"...txt");
    ...
    writer.Write("Hello World");
    ...
    writer.Flush(); // at this point the bytes are flushed to disk
    ...
    ...
    writer.Dispose();
    

    In short most streams are backed by an internal array (buffer), so you dont thrash writes. The Default size is 4k, when it hits the buffer size then it automatically flushes. If you want to see immediate writes, the you have to flush it every time

    Lastly some streams have an auto flush feature, which can do this job for you

    AutoFlush

    Gets or sets a value indicating whether the StreamWriter will flush its buffer to the underlying stream after every call to Write(Char)

    When you are finished with the stream always dispose it