Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I read exactly n bytes from a stream?

Tags:

c#

.net

stream

This is a little more tricky than I first imagined. I'm trying to read n bytes from a stream.

The MSDN claims that Read does not have to return n bytes, it just must return at least 1 and up to n bytes, with 0 bytes being the special case of reaching the end of the stream.

Typically, I'm using something like

var buf = new byte[size];
var count = stream.Read (buf, 0, size);

if (count != size) {
    buf = buf.Take (count).ToArray ();
}

yield return buf;

I'm hoping for exactly size bytes but by spec FileStream would be allowed to return a large number of 1-byte chunks as well. This must be avoided.

One way to solve this would be to have 2 buffers, one for reading and one for collecting the chunks until we got the requested number of bytes. That's a little cumbersome though.

I also had a look at BinaryReader but its spec also does not clearly state that n bytes will be returned for sure.

To clarify: Of course, upon the end of the stream the returned number of bytes may be less than size - that's not a problem. I'm only talking about not receiving n bytes even though they are available in the stream.

like image 258
mafu Avatar asked Sep 22 '11 11:09

mafu


People also ask

Which number of byte to be read into a buffer of the system is?

The read() system call reads the input typed by the user via the keyboard (file descriptor 0) and stores it in the buffer (buff) which is nothing but a character array. It will read a maximum of 10 bytes (because of the third parameter). This can be less than or equal to the buffer size.

How does stream read work?

read() method reads the next byte of the data from the the input stream and returns int in the range of 0 to 255. If no byte is available because the end of the stream has been reached, the returned value is -1.

What is stream of bytes in C#?

Stream is an abstract class for transfering bytes from different sources. It is base class for all other class that reads\writes bytes to different sources. FileStream class provides reading and writing functionality of bytes to physical file.


1 Answers

A slightly more readable version:

int offset = 0;
while (offset < count)
{
    int read = stream.Read(buffer, offset, count - offset);
    if (read == 0)
        throw new System.IO.EndOfStreamException();
    offset += read;
}

Or written as an extension method for the Stream class:

public static class StreamUtils
{
    public static byte[] ReadExactly(this System.IO.Stream stream, int count)
    {
        byte[] buffer = new byte[count];
        int offset = 0;
        while (offset < count)
        {
            int read = stream.Read(buffer, offset, count - offset);
            if (read == 0)
                throw new System.IO.EndOfStreamException();
            offset += read;
        }
        System.Diagnostics.Debug.Assert(offset == count);
        return buffer;
    }
}
like image 186
Andrei Bozantan Avatar answered Oct 08 '22 21:10

Andrei Bozantan