C# BinaryWriter
last modified April 20, 2025
This tutorial explains how to use the BinaryWriter class in C# to write binary data to files. BinaryWriter provides methods for writing primitive data types to streams.
The BinaryWriter class writes primitive data types as binary values in
a specific encoding. It works with the BinaryReader
class which
reads binary data.
BinaryWriter
is useful for creating compact binary files that store
data efficiently. It handles data types like int, float, double, and strings
with specified encodings.
Basic BinaryWriter Example
This example demonstrates writing primitive data types to a binary file. We create a new file and write several values of different types.
using System; using System.IO; class Program { static void Main() { using (var writer = new BinaryWriter(File.Open("data.bin", FileMode.Create))) { writer.Write(42); // Integer writer.Write(3.14159); // Double writer.Write(true); // Boolean writer.Write("Hello World"); // String } Console.WriteLine("Binary data written successfully"); } }
The program creates a binary file and writes four different primitive types.
BinaryWriter
provides overloaded Write methods for each data type.
The example writes an integer, a double, a boolean, and a string to the file.
Each Write method converts the value to a sequence of bytes and writes them to the stream. The string is written with a length prefix using UTF-8 encoding by default. This makes the file compact and efficient for storage.
Writing Arrays to Binary File
BinaryWriter can write arrays of primitive types. This example shows how to write an integer array to a binary file.
using System; using System.IO; class Program { static void Main() { int[] numbers = { 10, 20, 30, 40, 50 }; using (var writer = new BinaryWriter(File.Open("array.bin", FileMode.Create))) { writer.Write(numbers.Length); // Write array length first foreach (int num in numbers) { writer.Write(num); // Write each element } } Console.WriteLine("Array written to binary file"); } }
The array length is written first, followed by each element. This allows proper reconstruction when reading. The example writes the length of the array as an integer, then iterates through the array writing each element.
This pattern is common when working with arrays in binary files. The reader will first read the length, then know how many elements to read. This approach works for any primitive type array.
Writing Mixed Data Types
Binary files often contain mixed data types. This example demonstrates writing a structured binary file with different data types.
using System; using System.IO; class Program { static void Main() { using (var writer = new BinaryWriter(File.Open("product.bin", FileMode.Create))) { writer.Write("Laptop"); // String writer.Write(1001); // Integer ID writer.Write(999.99m); // Decimal price writer.Write(DateTime.Now.Ticks); // DateTime as ticks } Console.WriteLine("Mixed data written to binary file"); } }
The example writes a product record with string, integer, decimal, and DateTime values. Each Write method handles the appropriate binary conversion. The string is written with length prefix, numbers in their binary form.
DateTime is stored as ticks (long integer) for precise reconstruction. When reading, the order of reads must exactly match the order of writes to correctly interpret the binary data.
Specifying String Encoding
BinaryWriter supports different string encodings. This example shows how to specify encodings when writing strings.
using System; using System.IO; using System.Text; class Program { static void Main() { using (var writer = new BinaryWriter( File.Open("encoded.bin", FileMode.Create), Encoding.Unicode)) { writer.Write("Unicode text"); // Written as Unicode // Write UTF-8 string manually byte[] utf8Bytes = Encoding.UTF8.GetBytes("UTF-8 text"); writer.Write(utf8Bytes.Length); writer.Write(utf8Bytes); } Console.WriteLine("Strings written with different encodings"); } }
The BinaryWriter constructor accepts an Encoding parameter. By default it uses UTF-8. This example shows Unicode encoding and manual UTF-8 writing.
For full control, you can convert strings to bytes yourself using Encoding classes. This is useful when you need to mix encodings in the same file or use encodings not supported by BinaryWriter directly.
Writing to MemoryStream
BinaryWriter isn't limited to files - it can write to any Stream. This example uses MemoryStream to write binary data to memory.
using System; using System.IO; class Program { static void Main() { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { writer.Write(1.61803398875); // Golden ratio writer.Write("Fibonacci"); writer.Write(new byte[] { 0, 1, 1, 2, 3, 5, 8 }); // Get the written data byte[] data = stream.ToArray(); Console.WriteLine($"Wrote {data.Length} bytes to memory"); } } }
MemoryStream provides in-memory binary data storage. BinaryWriter treats it like any other stream destination. The example writes several values to memory.
This approach is useful for network protocols or serialization where you need binary data in memory rather than a file. The ToArray method retrieves the written bytes as a byte array.
Seeking and Writing at Position
BinaryWriter works with seekable streams. This example demonstrates seeking to a position and writing data.
using System; using System.IO; class Program { static void Main() { using (var stream = new FileStream("seek.bin", FileMode.Create)) using (var writer = new BinaryWriter(stream)) { // Write initial data writer.Write(100); writer.Write(200); // Save position of third value long thirdValuePos = stream.Position; writer.Write(0); // Placeholder writer.Write(400); writer.Write(500); // Go back and write the third value stream.Seek(thirdValuePos, SeekOrigin.Begin); writer.Write(300); } Console.WriteLine("File with seek operations written"); } }
The example writes some values, saves a position, writes more data, then goes back to update a placeholder. This demonstrates random access writing.
The BaseStream property provides access to the underlying stream for seeking. This technique is useful for file formats that require headers or need to update values after writing other data.
Writing Structs as Binary Data
This advanced example demonstrates writing C# structs as binary data using memory marshaling.
using System; using System.IO; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Point3D { public float X; public float Y; public float Z; public int Color; } class Program { static unsafe void Main() { Point3D point = new Point3D { X = 1.0f, Y = 2.0f, Z = 3.0f, Color = 0xFF0000 }; using (var writer = new BinaryWriter(File.Open("point.bin", FileMode.Create))) { byte[] buffer = new byte[Marshal.SizeOf(typeof(Point3D))]; fixed (byte* ptr = buffer) { Marshal.StructureToPtr(point, (IntPtr)ptr, false); writer.Write(buffer); } } Console.WriteLine("3D point struct written to binary file"); } }
The StructLayout attribute ensures proper binary alignment. Marshaling converts structured data to raw bytes. Requires unsafe compilation.
This technique is powerful for writing complex binary formats that match specific memory layouts. It's commonly used in graphics programming and interoperability scenarios.
Source
BinaryWriter Class Documentation
This tutorial covered writing binary data in C# with BinaryWriter, including primitive types, arrays, strings, and structured data.
Author
List all C# tutorials.