1

If I have the following code:

FileStream fs = new FileStream(...);
TextWriter tw = new StreamWriter(fs);

Am I supposed to call only tw.Close(), or fs.Close() as well? I'm using the TextWriter persistently throughout an application, so I can't just wrap it in a Using(...) block, since I need to be able to use it at multiple points.

Otherwise, I would just write it as:

using (FileStream fs = new FileStream(...))
{
    using (TextWriter tw = new StreamWriter(fs))
    {
       // do stuff
    }
}

And avoid the issue at all together. But, I don't really know what to do in this circumstance. Do I close tw, fs, or both?

Also, more generally: If I compose multiple streams together, such as C(B(A)), can I call Close / Dispose on C and then not worry about having to call it on B and A?

Mike Bailey
  • 12,479
  • 14
  • 66
  • 123

3 Answers3

4

You only need to close the StreamWriter.

From the documentation of the StreamWriter.Close method:

Closes the current StreamWriter object and the underlying stream.

Also notable in the documentation of the method:

This implementation of Close calls the Dispose method passing a true value.

This means that closing and disposing the StreamWriter are equivalent. You don't have to dispose the object after closing it, or close it before disposing it. The FileStream.Close method does the same, so closing or disposing the StreamWriter will also dispose the stream.

If you wouldn't be able to find information like this for a class, you can always dispose both the writer and the stream to be safe. Disposing an object that has already been disposed does not cause any problem, and the method would just do nothing. Just make sure to close them in the right order, i.e. closing the writer before the stream.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

Because you have already enclosed your stream declaration in a "using" statement you to not need to specifically do either. Using invokes dispose and the dispose invokes close.

See this article from SO

Community
  • 1
  • 1
Cos Callis
  • 5,051
  • 3
  • 30
  • 57
0

You're safe to Dispose() both tw and fs. If tw does happen to Dispose() the underlying stream, calling Dispose() again will be a no-op.

Update: Now I see the real question... In your case, I would turn to ILSpy which shows that TextWriter.Dispose() does indeed call Close() on the underlying stream. So you're fine to just call tw.Dispose().

dahlbyk
  • 75,175
  • 8
  • 100
  • 122