BinarySerializer is a small C#/.NET Framework library for writing typed values to a binary stream and reading them back later.
This project is old and no longer maintained. It targets .NET Framework 4.0 / Visual Studio 2010-era tooling, and part of its fallback serialization path uses BinaryFormatter, which is deprecated and unsafe for untrusted data. Treat this repository as historical code rather than a recommended serialization library for new projects.
The original goal was to get smaller binary output than BinaryFormatter for simple object graphs. BinaryFormatter writes assembly and class metadata into the stream, which can dominate the output when the values themselves are small.
For the sample List<object> shown below, BinaryFormatter serializes the graph to about 243 bytes. This serializer writes the same graph in 34 bytes by using compact one-byte type markers for known types.
The library wraps BinaryWriter and BinaryReader with that simple type marker protocol. BinarySerializationWriter.WriteObject(...) writes a value with a one-byte type identifier, and BinarySerializationReader reads that value back as either object or a requested generic type.
Supported direct types include:
- Numeric primitives:
byte,sbyte,short,ushort,int,uint,long,ulong,decimal, anddouble charstringboolDateTimeTimeSpannull- Lists and other
IEnumerablevalues - Dictionaries and other
IDictionaryvalues
Unsupported object types fall back to BinaryFormatter serialization.
using System;
using System.Collections.Generic;
using System.IO;
using com.AutopilotLlc.BinarySerializer;
var values = new List<object>
{
2172012,
406.1978,
"example",
new DateTime(2012, 2, 17)
};
using (var stream = new MemoryStream())
{
var writer = new BinarySerializationWriter(stream);
writer.WriteObject(values);
stream.Position = 0;
var reader = new BinarySerializationReader(stream);
List<object> roundTripped = reader.ReadList();
}Typed reads are also supported:
using (var stream = new MemoryStream())
{
new BinarySerializationWriter(stream).WriteObject(42);
stream.Position = 0;
int value = new BinarySerializationReader(stream).ReadObject<int>();
}The custom binary format has predictable overhead for directly supported types:
- Most primitive values are stored as
1type-marker byte plus their normal binary size. boolis stored as a single marker byte:TrueorFalse.nullis stored as a single marker byte.stringis stored as1type-marker byte, a 7-bit encoded byte length, and the encoded string bytes.- Collections and dictionaries are stored as
1type-marker byte, a 7-bit encoded item count, and each serialized child value.
For the example list above, the serialized graph is about 34 bytes:
List<object> marker + count 2 bytes
int 2172012 5 bytes
double 406.1978 9 bytes
string "example" 9 bytes
DateTime value 9 bytes
Total 34 bytes
The easiest way to verify an object's actual serialized size is the same helper used by the tests:
private static long SerializedLength(object item)
{
using (var stream = new MemoryStream())
{
new BinarySerializationWriter(stream).WriteObject(item);
return stream.Length;
}
}Use the estimate when reasoning about the format, and use the helper when you need the exact byte count for a specific object graph.
BinarySerializer/- the class libraryBinarySerializerTest/- MSTest tests covering primitive values, collections, dictionaries, nullable values, and null handlingBinarySerializer.sln- Visual Studio 2010 solution file
Open BinarySerializer.sln in Visual Studio and build the solution.
From a compatible .NET Framework/MSBuild environment, the project can also be built with:
msbuild BinarySerializer.slnThe test project uses MSTest through Microsoft.VisualStudio.QualityTools.UnitTestFramework.
Run the tests from Visual Studio Test Explorer, or from a compatible Visual Studio command prompt with the MSTest tooling available.
- The serialized format is project-specific and not intended as a stable cross-platform interchange format.
- The library writes type markers defined in
BinarySerializationType; changing that enum changes the wire format. BinaryFormattershould not be used with untrusted input. This repository preserves the original behavior for historical compatibility only.- No license file is currently included in this repository.