Skip to main content

Command Palette

Search for a command to run...

BinaryWriter and BinaryReader

What They Are, When to Use Them and How to Use Them

Published
3 min read

What They Are

BinaryWriter and BinaryReader are .NET classes that act as wrappers around a stream (like a FileStream or MemoryStream). Their purpose is to read and write primitive data types (int, double, bool, string, etc.) in a compact, non-human-readable binary format.

  • BinaryWriter converts data types into their raw byte representations and writes them to the underlying stream.

  • BinaryReader reads raw bytes from a stream and converts them back into their original data types.


When to Use Them

Use BinaryWriter and BinaryReader when your priority is performance and file size, and the data does not need to be read by a human in a text editor.

  • Compact File Size 💾: Storing data in its binary form is much smaller than its text representation. For example, the number 1000000 is 7 characters as a string but only 4 bytes as a binary int.

  • High Performance 🚀: Reading and writing binary data is faster than parsing text-based formats like JSON or XML because there is no complex parsing or text conversion involved.

  • Fixed Data Structures: They are perfect for creating custom file formats with a strict structure, such as application settings, game save files, or network data packets.


How to Use Them

The core principle is to read the data in the exact same order and type as it was written.

C# Example

This example writes an ID, a username, and a score to a binary file and then reads it back.

string filePath = "player.dat";

// --- Writing Data with BinaryWriter ---
try
{
    using (var writer = new BinaryWriter(File.Open(filePath, FileMode.Create)))
    {
        // Write data in a specific order
        writer.Write(101);                // Player ID (int)
        writer.Write("PlayerOne");        // Username (string)
        writer.Write(9500.50);            // Score (double)
        writer.Write(true);               // IsActive (bool)
    }
    Console.WriteLine("Data saved successfully.");
}
catch (IOException e)
{
    Console.WriteLine($"Error writing file: {e.Message}");
}


// --- Reading Data with BinaryReader ---
try
{
    using (var reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
    {
        // Read data in the EXACT same order and type
        int id = reader.ReadInt32();
        string username = reader.ReadString();
        double score = reader.ReadDouble();
        bool isActive = reader.ReadBoolean();

        Console.WriteLine("\n--- Player Data ---");
        Console.WriteLine($"ID: {id}");
        Console.WriteLine($"Username: {username}");
        Console.WriteLine($"Score: {score}");
        Console.WriteLine($"Is Active: {isActive}");
    }
}
catch (IOException e)
{
    Console.WriteLine($"Error reading file: {e.Message}");
}

Key Concerns and Considerations

  1. Strict Order is Crucial ⚠️: The biggest concern is that you must read the data in the identical sequence and with the correct data types it was written. Reading an int where a double was written will result in corrupted data and likely throw an exception. The file itself has no metadata to describe its structure.

  2. Not Human-Readable: The output files (.bin, .dat, etc.) are binary and will look like gibberish if opened in a standard text editor. This makes manual inspection and debugging difficult.

  3. Cross-Platform Portability (Endianness): By default, BinaryWriter uses little-endian byte order. If you share binary files with a system that uses big-endian order (like some older hardware or network protocols), the multi-byte values (int, double, etc.) will be misinterpreted. This is an advanced concern but critical for cross-platform applications.

  4. Write(string) Format: BinaryWriter.Write(string) uses a specific format called a length-prefixed string. It first writes the length of the string as a compact integer, then writes the string's character bytes. BinaryReader.ReadString() expects this format. You cannot use it to read a string from a plain text file.