It should be:
public class Block
{
public long Timestamp { get; set; }
public byte[][] DataBlock1 { get; set; } = new byte[600][];
public byte[][] DataBlock2 { get; set; } = new byte[600][];
}
and then
var lst = new List<Block>();
var enc = Encoding.GetEncoding("iso-8859-1");
using (var fs = File.OpenRead("somefile.bin"))
using (var br = new BinaryReader(fs, enc))
{
while (br.PeekChar() != -1)
{
var block = new Block();
block.Timestamp = br.ReadInt64();
for (int i = 0; i < block.DataBlock1.Length; i++)
{
block.DataBlock1[i] = br.ReadBytes(16);
if (block.DataBlock1[i].Length != 16)
{
throw new Exception();
}
}
for (int i = 0; i < block.DataBlock2.Length; i++)
{
block.DataBlock2[i] = br.ReadBytes(16);
if (block.DataBlock2[i].Length != 16)
{
throw new Exception();
}
}
lst.Add(block);
}
}
In the end you use a FileStream (returned by File.OpenRead()) and on top of that you put a BinaryReader. I read 16 bytes at a time with BinaryReader, but would be perhaps faster to read multiple "rows" at a time and then split them (a DataBlockX is 9600 bytes, so it isn't too much big). For the EOF handling, I've used BinaryReader.PeekChar, as suggested by Marc Gravell. But note that I concur with the problems presented by some persons, so I'm using the iso-8859-1 encoding, that guarantees that any byte is ok for the method (the default solution suggested by Gravell will break for some combination of bytes)
Something like:
public static void ReadDataBlock(BinaryReader br, byte[][] dataBlock, int size)
{
int totalSize = dataBlock.Length * size;
byte[] bytes = br.ReadBytes(totalSize);
if (bytes.Length != totalSize)
{
throw new Exception();
}
for (int i = 0; i < dataBlock.Length; i++)
{
var block = new byte[size];
dataBlock[i] = block;
Buffer.BlockCopy(bytes, i * size, block, 0, size);
}
}
and then:
block.Timestamp = br.ReadInt64();
ReadDataBlock(br, block.DataBlock1, 16);
ReadDataBlock(br, block.DataBlock2, 16);