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.