views:

2216

answers:

4

I am sending a stream to methods to write on, and in those methods I am using a binary reader/wrtier. When the reader/writer gets disposed, either by using or just when it is not referenced, is the stream closed as well??

I would send a BinaryReader/Writer, but I am using a StreamReader too (maybe I should go around that. I am only using that for GetLine and ReadLine). This is quite troublesome if it closes the stream each time a writer/reader gets closed.

A: 

the stream disposed either by "using" keyword or calling dispose explicitly

Ahmed Said
+1  A: 

Yes, it does. You can verify this by looking at the implementation with Reflector.

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {    
            this.stream = null;    
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}
Brian Rasmussen
A: 

Yes. Calling Dispose() on and IDisposable (which "using" does) should make an object clean up all of its resources. This includes streams flushing and closing their file descriptors.

If, in your case, you want to pass it in to other methods, then you need to make sure that those methods do not do their reading/writing in a using block.

Joe M
+13  A: 

Yes, StreamReader, StreamWriter, BinaryReader and BinaryWriter all close/dispose their underlying streams when you call Dispose on them. They don't dispose of the stream if the reader/writer is just garbage collected though - you should always dispose of the reader/writer, preferrably with a using statement. (In fact, none of these classes have finalizers, nor should they have.)

Personally I prefer to have a using statement for the stream as well. You can nest using statements without braces quite neatly:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

Even though the using statement for the stream is somewhat redundant (unless the StreamReader constructor throws an exception) I consider it best practice as then if you get rid of the StreamReader and just use the stream directly at a later date, you'll already have the right disposal semantics.

Jon Skeet
oh good, it only happens when calling Dispose, not when supposedly finalizing.
Nefzen
@Nefzen: That's because there is no guarantee what order your objects will be finalized. If both the StreamReader and the underlying Stream are eligible for finalization, the GC might finalize the stream first -- then streamreader would not have a reference to stream. For this reason, you can only release unmanaged resources inside of a finalize (for example, a FileStream closes its windows file handle in its finalize). Oh, and of course, if you never dispose, the stream will still be collected eventually(and the file closed). It's just a very bad practice to not dispose a stream.
JMarsch