3

Can I create a new BinaryWriter and write on a Stream, while the stream is already beeing used by another BinaryWriter?

I need to write some data recursively, but I would like to avoid passing a BinaryWriter to a method as a parameter, as I need to pass a Stream instead. So, each method that will write data on the stream may need to create its own BinaryWriter instance. But I don't know if this is right. For now, it works well on a FileStream, but I don't know if it could lead to unexpected results on the users machines.

I wrote a simple example of what I want to achieve. Is this use of the BinaryWriter wrong?

Example:

public Main()
{
    using (var ms = new MemoryStream())
    {
        // Write data on the stream.
        WriteData(ms);
    }
}

private void WriteData(Stream output)
{
    // Create and use a BinaryWriter to use only on this method.
    using (var bWriter = new BinaryWriter(output, Encoding.UTF8, true))
    {
        // Write some data using this BinaryWriter.
        bWriter.Write("example data string");
        // Send the stream to other method and write some more data there.
        WriteMoreData(output);
        // Write some more data using this BinaryWriter.
        bWriter.Write("another example data string");
    }
}

private void WriteMoreData(Stream output)
{
    // Create and use a BinaryWriter to use only on this method.
    using (var bWriter = new BinaryWriter(output, Encoding.Unicode, true))
    {
        // Write some data on this BinaryWriter.
        bWriter.Write("write even more example data here");
    }
}
6
  • why not make it recursive ? Commented Aug 26, 2016 at 1:21
  • Looks okay to me. You, of course, need to go through all your usual rounds of testing to catch as many issues of possible, before you go with any code to users. By then you should be confident, that your code works as intended. Commented Aug 26, 2016 at 1:24
  • And would I need to call Flush() on the BinaryWriter before writing on its Stream using other instance of BinaryWriter? Commented Aug 26, 2016 at 1:26
  • Another facet here is that whether or not you expect this code to work with any other types of stream than you mentioned. If you do, you need to write corresponding unit tests. For example, there are streams that are not writable. Commented Aug 26, 2016 at 1:27
  • BinaryWriter.Flush just calls underlying Stream.Flush. That's all it does. Commented Aug 26, 2016 at 1:28

1 Answer 1

2

Is this use of the BinaryWriter wrong?

It should work fine. BinaryWriter does no buffering itself, so each instance won't interfere with data written by other instances. You're passing true for the leaveOpen parameter, so when each instance is disposed, it won't close the underlying stream.

But "wrong" is to some degree in the eye of the beholder. I would say it's better to pass the BinaryWriter.

MemoryStream isn't buffered, but other types are. Each instance of BinaryWriter, when it's disposed, will flush the stream. This could be considered inefficient by some people, as it negates the benefit of the buffering, at least partially. Not an issue here, but may not be the best habit to get into.

In addition, each instance of BinaryWriter is going to create additional work for the garbage collector. If there's really only a few, that's probably not an issue. But if the real-world example involves a lot more calls, that could start to get noticeable, especially when the underlying stream is a MemoryStream (i.e. you're not dealing with some slow device I/O).

More to the point, I don't see any clear advantage to using multiple BinaryWriter instances on the same stream here. It seems like the natural, readable, easily-maintained thing to do would be to create a single BinaryWriter and reuse it until you're done writing.

Why do you want to avoid passing it as a parameter? You're already passing the Stream. Just pass the BinaryWriter instead. If you ever did need direct access to the underlying stream, it's always available via BinaryWriter.BaseStream.

Bottom line: I can't say there's anything clearly wrong per se with your proposal. But it's a deviation from normal conventions without (to me, anyway) a clear benefit. If you have a really good rationale for doing it this way, it should work. But I'd recommend against it.

Sign up to request clarification or add additional context in comments.

1 Comment

This answers very well my question. I was passing the Stream as a parameter, mainly because I would need to use the Stream to write data with XDocument.Save() on some methods, But your suggestion of using the BinaryWriter.BaseStream makes a lot more sense. I was no sure about the BinaryWriter using some kind of buffering and your answer provided me that information. Thank you! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.