What does BinaryReader do if my bytes are not already present?

I am using BinaryReader on top of NetworkStream to read data from the network. This worked very well for me, but I want to understand what is going on behind the scenes, so I looked at the documentation for BinaryReader and found that it was very rare.

My question is: what will BinaryReader.ReadBytes(bufferSize) if bufferSize bytes are not in the network stream when I call ReadBytes ?

In my mind there are several options:
1) Read all the bytes that are present in the network stream, and return only that many
2) Wait until bufferSize bytes are found bufferSize stream, and then read
3) Throw an exception

I assume option 2 is happening, since I have never received any exceptions, and all my data is received in whole, not in parts. However, I would like to know exactly what is happening. If anyone could enlighten me, I would be grateful.

+7
source share
2 answers

I believe that there is actually hidden option 4:

  • Read the data as it becomes available, looping in the same way as usual by hand. It will return a value less than the number of bytes you requested if it reaches the end of the stream while reading.

This is slightly different from your option 2, as it merges the stream as the data becomes available - it does not wait until it can read all the data in one go.

It is easy to show that it returns fewer bytes than you requested if it reaches the end:

 var ms = new MemoryStream(new byte[10]); var readData = new BinaryReader(ms).ReadBytes(100); Console.WriteLine(readData.Length); // 10 

It is harder to prove part of the loop, without a user thread that explicitly requires several Read calls to return all the data.

The documentation is not as clear as it can be, but part of the return value is at least somewhat useful:

A byte array containing data read from the underlying stream. This may be less than the number of bytes requested if the end of the stream is reached .

Pay attention to the final part that I have selected and compare it with Stream.Read :

The total number of bytes read in the buffer. This can be less than the number of bytes requested if the number of bytes is currently not available , or zero (0) if the end of the stream is reached.

If you expect an exact amount of data, and only this amount will be useful, I suggest you write a ReadExactly method that throws Read and throws EndOfStreamException if you need more data than the stream provided before it was closed.

+9
source

If, "present in the stream", you ask whether the method will be blocked until the specified number of bytes is available, then this is option 2. It will return fewer bytes if the end of the stream.

Here is a sample code on which you can implement BinaryReader.ReadBytes(int) :

 byte[] ReadBytes(int count) { byte[] buffer = new byte[count]; int total = 0; int read = 0; do { read = stream.Read(buffer, read, count - total); total += read; } while (read > 0 && total < count); // Resize buffer if smaller than count (code not shown). return buffer; } 
0
source

All Articles