You cannot do this with BinaryFormatter - it will expect additional metadata / additions around the object. You will have to read it manually using either Stream or a binary reader.
Having made very similar code, I would write my own reader, which sits on top of the stream, with methods such as: ReadInt32LittleEndian , ReadInt32BigEndian (etc. for everything you need) - and use shift ( << / >> ) to build bytes. But it is important that I use a support buffer to reduce the number of calls to the underlying stream (even with a buffer, this can be unacceptably slow).
Let me direct you to some code from protobuf-net that does this ... specifically ProtoReader , taking an example:
/// <summary> /// Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public uint ReadUInt32() { switch (wireType) { case WireType.Variant: return ReadUInt32Variant(false); case WireType.Fixed32: if (available < 4) Ensure(4, true); position += 4; available -= 4; return ((uint)ioBuffer[ioIndex++]) | (((uint)ioBuffer[ioIndex++]) << 8) | (((uint)ioBuffer[ioIndex++]) << 16) | (((uint)ioBuffer[ioIndex++]) << 24); case WireType.Fixed64: ulong val = ReadUInt64(); checked { return (uint)val; } default: throw CreateException(); } }
(here wireType generally acts as an indicator of continent etc., but that doesn't matter)
Looking at the implementation of Fixed32 :
Ensure guarantees that we have at least 4 more bytes in our backup buffer (extracting more if we wish)- we increase the number of counters to track our position in the logical buffer
- we read data from the buffer
You have a reader for your format, deserialization should be much easier.
source share