15

Both BinaryReader constructors require a stream parameter. If I need to keep the underlying stream as-is when I'm done with the BinaryReader, should I still call its Dispose()? If not, is there any other clean-up for the no longer needed BinaryReader?

I'm asking because I can't find a clear answer on MSDN page for BinaryReader.Dispose().

Small addtion

In my context I use the BinaryReader to read a couple of bytes, after which I set the position of the stream back to what it was before the BinaryReader was initialized.

Also, I'm using .Net 4.

4 Answers4

22

If you (or anyone else reading these looking for an answer) are using VS 2012 with .NET 4.5 (or later) you can create a BinaryReader that won't close the stream. E.g.:

using(var reader = new BinaryReader(theStream, new UTF8Encoding(), true)
{
//...
}

new UTF8Encoding is the default if you used the BinaryReader(Stream) constructor, if you don't want UTF8Encoding, you can use something else. The true signifies "yes, leave the stream open".

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
12

No, it's fine to not dispose of the BinaryReader if you want to keep the stream open.

I'd probably add a comment to explain what's going on though - and I'm not sure whether it's guaranteed that the BinaryReader will have only read from the stream as far as you've read from the BinaryReader... it might have read more into a buffer, for example. Obviously that's not a problem if you then seek on the stream.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • yes I updated my question to mention I only read a couple of bytes with the `BinaryReader`. –  Aug 29 '12 at 16:20
4

There is already an accepted answer, but it makes me feel dirty :-) I think we can do better:

  1. If you're using .NET 4.5, you should use the 3-arg constructor of BinaryReader. Done.
  2. If you're using .NET 3.5/4.0, you need a different solution

Jon Skeet (the accepted answer) suggests to just never dispose the BinaryReader. Well, that works ofcourse, but could be a source of confusion.

An alternative solution could be to wrap your Stream in a NonClosingStreamWrapper, before passing that to BinaryReader. The BinaryReader will close the wrapper when it gets disposed, but the NonClosingStreamWrapper will not dispose your underlying Stream. You can still use .Dispose on the binaryStream (or even better, the using-pattern).

Very ironically, @JonSkeet already created a NonClosingStreamWrapper to do just that. It's part of his miscutil library. (but note the license)

using(var reader = new BinaryReader(new NonClosingStreamWrapper(myStream)))
{
//...
}
toong
  • 1,360
  • 12
  • 18
2

If it was me, I'd dispose of the BinaryReader, just for the sake of tidyness...but I'd also ensure that I created the BinaryReader with this this constructor overload:

public BinaryReader(
  Stream   input,
  Encoding encoding,
  bool     leaveOpen
  )

where specifying the leaveOpen argument as true instructs the reader to leave the underlying stream open.

Going this route, you make explicit the scope and ownership of things. Less room for confusion and misunderstanding that way.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • 1
    I agree with your comment 100%, and I would've probably have not asked the question if I was using 4.5 because I would've probably noticed the `leaveOpen` argument. –  Aug 29 '12 at 16:38