Does disposing streamreader close the stream?
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.
Does .Disposing a StreamWriter close the underlying stream?
StreamWriter.Close() just calls StreamWriter.Dispose() under the bonnet, so they do exactly the same thing.
StreamWriter.Dispose() does close the underlying stream.
Reflector is your friend for questions like this :)
Should I call Close() or Dispose() for stream objects?
A quick jump into Reflector.NET shows that the Close()
method on StreamWriter
is:
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
And StreamReader
is:
public override void Close()
{
this.Dispose(true);
}
The Dispose(bool disposing)
override in StreamReader
is:
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;
/* deleted for brevity */
base.Dispose(disposing);
}
}
}
The StreamWriter
method is similar.
So, reading the code it is clear that that you can call Close()
& Dispose()
on streams as often as you like and in any order. It won't change the behaviour in any way.
So it comes down to whether or not it is more readable to use Dispose()
, Close()
and/or using ( ... ) { ... }
.
My personal preference is that using ( ... ) { ... }
should always be used when possible as it helps you to "not run with scissors".
But, while this helps correctness, it does reduce readability. In C# we already have plethora of closing curly braces so how do we know which one actually performs the close on the stream?
So I think it is best to do this:
using (var stream = ...)
{
/* code */
stream.Close();
}
It doesn't affect the behaviour of the code, but it does aid readability.
Disposing a StreamReader that read a stream that is defined out of scope?
You could invert control using a closure. That is, create a method like so:
// This method will open the stream, execute the streamClosure, and then close the stream.
public static String StreamWork(Func<Stream, String> streamClosure) {
// Set up the stream here.
using (Stream stream = new MemoryStream()) { // Pretend the MemoryStream is your actual stream.
// Execute the closure. Return it's results.
return streamClosure(stream);
}
}
which is responsible for opening / closing the stream within the method.
Then you simply wrap up all the code that needs the stream into a Func<Stream, String>
closure, and pass it in. The StreamWork
method will open the stream, execute your code, then close the stream.
public static void Main()
{
// Wrap all of the work that needs to be done in a closure.
// This represents all the work that needs to be done while the stream is open.
Func<Stream, String> streamClosure = delegate(Stream stream) {
using (StreamReader streamReader = new StreamReader(stream)) {
return streamReader.ReadToEnd();
}
};
// Call StreamWork. This method handles creating/closing the stream.
String result = StreamWork(streamClosure);
Console.WriteLine(result);
Console.ReadLine();
}
UPDATE
Of course, this method of inversion is a matter of preference as mentioned in the comments below. The key point is to ensure that the stream is closed rather than allowing it to float around until the GC cleans it up (since the whole point of having stuff implement IDisposable
is to avoid that sort of situation to begin with). Since this is a library function that accepts a Stream
as input, the assumption is that the method-consumer will be creating the stream, and therefore as you point out, has the responsibility of ultimately closing the stream as well. But for sensitive resources where you are concerned about ensuring clean up occurs absolutely, inversion is sometimes a useful technique.
Is there a benefit in closing StreamReader (or StreamWriter) when I close Stream explicitly?
You do need to close a StreamWriter
(generally via the using
block), or else data in its buffer could be lost.
Because both StreamReader
and StreamWriter
default to closing the stream automatically, if you want to eliminate one using
block from your code, it should be the Stream
that you remove from using
.
If you can't do that, for example you've borrowed the Stream
from elsewhere that doesn't want you to close it, then you must use the leaveOpen
parameter you're already aware of. The reason that you can't just omit the using
statement for a StreamReader
/StreamWriter
in order to leave it open, is that the garbage collector will still trigger some cleanup (although not as much) since the object is unreachable... only this will now occur at an unrelated time, creating an unpredictable bug that's very hard to find.
It is indeed ugly that you can't specify leaveOpen
without explicitly controlling the buffer size, etc. May I suggest a helper method along the lines of StreamReader CreateStreamReaderLeaveOpen(Stream)
?
Will closing a FileStream close the StreamReader?
Essentially yes. You don't actually have to close a StreamReader. If you do, all it does is closes the underlying stream.
@Bruno makes a good point about closing the outer-most wrapper. It is good practice to close the outer-most stream and let it close underlying streams in order to ensure all resources are released properly.
From Reflector...
public class StreamReader : TextReader
{
public override void Close()
{
this.Dispose(true);
}
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);
}
}
}
}
Leave StreamReader without closing Stream
There is an overload of the StreamReader
constructor which accepts a bool leaveOpen
parameter. Passing true
prevents the StreamReader
from closing the stream when the StreamReader
is disposed.
leaveOpen
Type: System.Boolean
true to leave the stream open after the StreamReader object is disposed; otherwise, false.
Example, using the default UTF8 encoding and 1024-byte buffer that you get with the simpler StreamReader
constructors:
using (var reader = new StreamReader(stream, Encoding.UTF8, true, 1024, true))
{
// use reader
} // stream will NOT be closed here
Can you keep a StreamReader from disposing the underlying stream?
I don't want to just let it go out of scope, either. Then the garbage collector will eventually call the Dispose, killing the stream.
Garbage collector will call the Finalize
method (destructor), not the Dispose
method. The finalizer will call Dispose(false)
which will not dispose the underlying stream. You should be OK by leaving the StreamReader
go out of scope if you need to use the underlying stream directly. Just make sure you dispose the underlying stream manually when it's appropriate.
Why disposing StreamReader makes a stream unreadable?
This happens because the StreamReader
takes over 'ownership' of the stream. In other words, it makes itself responsible for closing the source stream. As soon as your program calls Dispose
or Close
(leaving the using
statement scope in your case) then it will dispose the source stream as well. Calling fs.Dispose()
in your case. So the file stream is dead after leaving the first using
block. It is consistent behavior, all stream classes in .NET that wrap another stream behave this way.
There is one constructor for StreamReader
that allows saying that it doesn't own the source stream. It is however not accessible from a .NET program, the constructor is internal.
In this particular case, you'd solve the problem by not using the using
-statement for the StreamReader
. That's however a fairly hairy implementation detail. There's surely a better solution available to you but the code is too synthetic to propose a real one.
Does Stream.Dispose always call Stream.Close (and Stream.Flush)
Can I just call MySW.Dispose() and
skip the Close even though it is
provided?
Yes, that’s what it’s for.
Are there any Stream implementations
that don't work as expected (Like
CryptoStream)?
It is safe to assume that if an object implements IDisposable
, it will dispose of itself properly.
If it doesn’t, then that would be a bug.
If not, then is the following just bad
code:
No, that code is the recommended way of dealing with objects that implement IDisposable
.
More excellent information is in the accepted answer to Close and Dispose - which to call?
Related Topics
What Does the '=>' Syntax in C# Mean
Can a C# Thread Really Cache a Value and Ignore Changes to That Value on Other Threads
Raise an Event Whenever a Property's Value Changed
If Statements Matching Multiple Values
Finding All Positions of Substring in a Larger String in C#
Why Can't an Anonymous Method Be Assigned to Var
Best Way to Resolve File Path Too Long Exception
How to Seed a Random Class to Avoid Getting Duplicate Random Values
How to Serialize/Deserialize to 'Dictionary<Int, String>' from Custom Xml Not Using Xelement
Calling a Method Every X Minutes
Why Can't I Have Abstract Static Methods in C#
Is There a .Net/C# Wrapper for SQLite
How to Enable Http Put and Delete for ASP.NET MVC in Iis