Streamからデータを読み込むには、Readメソッドを使います。 Readメソッドの引数・戻り値は次のとおりです。

第1引数 buffer
Streamから読み込んだデータを格納するためのバイト配列
第2引数 offset
Streamから読み込んだデータを格納する際の、格納先となるバイト配列中の開始インデックス
第3引数 count
Streamから読み込むデータの最大バイト数
戻り値
実際にStreamから読み込めたデータのバイト数

つまり、Readメソッドの戻り値をlenとすると、ReadメソッドでStreamから読み込んだデータはbuffer[offset]からbuffer[offset + len - 1]の範囲に格納されることになります。

Readメソッドを使ってStreamからデータを読み込む
using System;
using System.IO;

class Sample {
  static void Main()
  {
    using (var stream = File.OpenRead("sample.dat")) {
      // 読み込んだデータを格納するためのバッファ
      var buffer = new byte[8];

      // streamから最大4バイトを読み込み、buffer[0]以降に格納する
      var len = stream.Read(buffer, 0, 4);

      // 実際に読み込めた分を表示する
      Console.WriteLine("{0} {1}", len, BitConverter.ToString(buffer, 0, len));

      // streamから最大2バイトを読み込み、buffer[4]以降に格納する
      len = stream.Read(buffer, 4, 2);

      // 実際に読み込めた分を表示する
      Console.WriteLine("{0} {1}", len, BitConverter.ToString(buffer, 4, len));
    }
  }
}

上記の例で使用しているBitConverter.ToStringメソッドはバイト配列を見やすい形式に変換するためのもので、Readメソッドを使った読み込み処理の本質とは無関係のものです

Readメソッドでは、指定したバイト数の分だけ読み込みを試みますが、指定したバイト数ちょうどのデータが一度に読み込まれるとは限りません。 例えば、読み込んだ結果ストリームの終端に達した場合や、NetworkStreamにおいてデータが送受信の途中だった場合などは、Readメソッドが読み込むバイト数は指定したバイト数よりも少なくなります。