Search code examples
c#.netio

fail to read it all into memory when shortcount reading


My textbook says:

Read receives a block of data from the stream into an array. It returns the number of bytes received, which is always either less than or equal to the count argument. If it’s less than count, it means either that the end of the stream has been reached or the stream is giving you the data in smaller chunks (as is often the case with network streams). In either case, the balance of bytes in the array will remain unwritten, their previous values preserved. With Read, you can be certain you’ve reached the end of the stream only when the method returns 0. So, if you have a 1,000-byte stream, the following code may fail to read it all into memory:

// Assuming s is a stream:
byte[] data = new byte [1000];
s.Read (data, 0, data.Length);

The Read method could read anywhere from 1 to 1,000 bytes, leaving the balance of the stream unread.

I'm confused and I write a simple concolse application to verify:

//read.txt only contains 3 chars: abc
using (FileStream s = new FileStream("read.txt", FileMode.Open))
{
   byte[] data = new byte[5];
   int num = s.Read(data, 0, data.Length);
   foreach (byte b in data)
   {
      Console.WriteLine(b);
   }
}

and the output is:

97

98

99

0

0

so the data array has been written, why the textbook says "the balance of bytes in the array will remain unwritten and it may fail to read it all into memory",

EDIT: please discard my previous console application, the real question I have is:

a file has 1000 byte and I'm requesting to read all 1000 bytes:

byte[] data = new byte [1000];
s.Read (data, 0, data.Length);

why it may fail to read it all into memory? and the textbook also provides a correct method to read all 1000 bytes:

byte[] data = new byte [1000];
int bytesRead = 0;
int chunkSize = 1;
while (bytesRead < data.Length && chunkSize > 0)
 bytesRead +=
 chunkSize = s.Read (data, bytesRead, data.Length - bytesRead);

Solution

  • If it’s less than count, it means either that the end of the stream has been reached or the stream is giving you the data in smaller chunks (as is often the case with network streams). In either case, the balance of bytes in the array will remain unwritten, their previous values preserved.

    When the text says In either case, it refers to If it’s (the return value, i.e the bytes read from the stream) less than count. In this case, the bytes read don't take up all the buffer area you have designated to the read action. The rest of the buffer area is, of course, untouched (remain unwritten, their previous values preserved).

    In your case, it is that the end of the stream has been reached because you only have 3 bytes in your file stream. The trailing zeros in your array are the untouched buffer elements.

    So, if you have a 1,000-byte stream, the following code may fail to read it all into memory.

    The text is talking about a 1,000-byte stream, while your stream just contains 3 bytes. For a short file stream that has only 3 bytes, it is likely that all data will be loaded into memory at once, which is the case you have observed. (just "likely", not "guaranteed"). For a longer stream (or other types of stream, e.g. NetworkStream), you are not guarunteed to read bytes enough to fill your designated buffer area at once (there are possibilities that you may even get only 1 bytes at a time!).