4

Consider the following function:

    private int GetSomethingFromFile(FileStream fs) 
    {
        using (BinaryReader br = new BinaryReader(fs))
        {
            fs.Seek(0, SeekOrigin.Begin);
            return br.ReadInt32();
        }
    }

A FileStream object is passed in as a parameter and a BinaryReader is declared with a using statement. When I try to use that FileStream object, after calling this function, it throws a System.ObjectDisposedException. Why is that FileStream object being disposed of along with the BinaryReader object?

raven
  • 18,004
  • 16
  • 81
  • 112
  • Related questions [here](http://stackoverflow.com/questions/1084813/why-a-binarywriter-closes-the-outer-stream-on-disposal-and-how-to-prevent-that) and [here](http://stackoverflow.com/questions/1633672/how-do-i-fork-a-stream-in-net) – raven Mar 10 '11 at 15:33

2 Answers2

8

It is a very good question, and I don't know why it was decided that this was how it should be, but alas it is documented to be this way:

BinaryReader class

Close: Closes the current reader and the underlying stream.

If you check out this answer to the question How do I “fork” a Stream in .NET? then you'll see that he refers to a class called NonClosingStreamWrapper in a library called MiscUtil that @Jon Skeet has written that you can use to wrap around the stream to prevent it from being closed.

You would use it like this (for your example):

private int GetSomethingFromFile(FileStream fs) 
{
    using (var wrapper = new NonClosingStreamWrapper(fs))
    using (BinaryReader br = new BinaryReader(wrapper))
    {
        fs.Seek(0, SeekOrigin.Begin);
        return br.ReadInt32();
    }
}
Community
  • 1
  • 1
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • Well, that sucks. I need that stream after I call the function. I'm just supposed to go against recommended practice and forgo the using statement? – raven Mar 10 '11 at 14:42
  • To be honest, either way is a "hack", either you drop the using-statement, or you make the wrapper class ignore that call. I have been using a similar wrapper myself though so that's what I would do. – Lasse V. Karlsen Mar 10 '11 at 14:46
1

Because disposing the binary reader disposes its underlying stream.

Use "using" in the caller method instead.

The reason is arbitrary: .NET class library is implemented this way.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206