.NET BinaryReader & BinaryWriter
Working with binary data is a fundamental skill for many programming tasks, from file processing to network communication. .NET provides specialized tools for handling binary data through the BinaryReader and BinaryWriter classes.
Introduction to Binary I/O
Binary I/O (Input/Output) deals with reading and writing data in its binary form rather than as text. This approach offers several advantages:
- Efficiency: Binary data typically takes less space than text representations
 - Precision: No conversion issues with floating-point numbers
 - Speed: Faster reading and writing of primitive data types
 - Structure preservation: Maintains the exact format of complex data structures
 
The .NET Framework provides two key classes for binary I/O operations:
BinaryReader: Reads primitive data types as binary values from a streamBinaryWriter: Writes primitive data types in binary format to a stream
BinaryReader Class
The BinaryReader class reads primitive data types from a stream as binary values. It's located in the System.IO namespace.
Creating a BinaryReader
To create a BinaryReader instance, you need to provide a stream:
using System;
using System.IO;
// Create a file stream
using (FileStream fileStream = new FileStream("data.bin", FileMode.Open))
{
    // Create a binary reader from the file stream
    using (BinaryReader reader = new BinaryReader(fileStream))
    {
        // Use the reader here
    }
}
Reading Data with BinaryReader
The BinaryReader class provides methods for reading different data types:
using System;
using System.IO;
using (FileStream fileStream = new FileStream("data.bin", FileMode.Open))
using (BinaryReader reader = new BinaryReader(fileStream))
{
    byte byteValue = reader.ReadByte();
    int intValue = reader.ReadInt32();
    double doubleValue = reader.ReadDouble();
    string stringValue = reader.ReadString();
    bool boolValue = reader.ReadBoolean();
    
    Console.WriteLine($"Byte: {byteValue}");
    Console.WriteLine($"Integer: {intValue}");
    Console.WriteLine($"Double: {doubleValue}");
    Console.WriteLine($"String: {stringValue}");
    Console.WriteLine($"Boolean: {boolValue}");
}
Common BinaryReader Methods
| Method | Description | 
|---|---|
ReadBoolean() | Reads a Boolean value (1 byte) | 
ReadByte() | Reads a single byte | 
ReadChar() | Reads a character (2 bytes) | 
ReadInt16() | Reads a 2-byte signed integer | 
ReadInt32() | Reads a 4-byte signed integer | 
ReadInt64() | Reads an 8-byte signed integer | 
ReadSingle() | Reads a 4-byte floating-point value | 
ReadDouble() | Reads an 8-byte floating-point value | 
ReadString() | Reads a string prefixed with its length | 
ReadBytes(int count) | Reads the specified number of bytes | 
BinaryWriter Class
The BinaryWriter class writes primitive data types to a stream as binary values. It's also located in the System.IO namespace.
Creating a BinaryWriter
Similar to BinaryReader, you create a BinaryWriter instance by providing a stream:
using System;
using System.IO;
// Create a file stream
using (FileStream fileStream = new FileStream("output.bin", FileMode.Create))
{
    // Create a binary writer from the file stream
    using (BinaryWriter writer = new BinaryWriter(fileStream))
    {
        // Use the writer here
    }
}
Writing Data with BinaryWriter
The BinaryWriter class provides methods for writing different data types:
using System;
using System.IO;
using (FileStream fileStream = new FileStream("output.bin", FileMode.Create))
using (BinaryWriter writer = new BinaryWriter(fileStream))
{
    writer.Write((byte)42);        // Write a byte
    writer.Write(12345);           // Write an integer
    writer.Write(3.14159);         // Write a double
    writer.Write("Hello, Binary"); // Write a string
    writer.Write(true);            // Write a boolean
}
Console.WriteLine("Data written successfully to output.bin");
Common BinaryWriter Methods
| Method | Description | 
|---|---|
Write(bool) | Writes a Boolean value (1 byte) | 
Write(byte) | Writes a single byte | 
Write(char) | Writes a character (2 bytes) | 
Write(short) | Writes a 2-byte signed integer | 
Write(int) | Writes a 4-byte signed integer | 
Write(long) | Writes an 8-byte signed integer | 
Write(float) | Writes a 4-byte floating-point value | 
Write(double) | Writes an 8-byte floating-point value | 
Write(string) | Writes a string prefixed with its length | 
Write(byte[], int, int) | Writes a range from a byte array | 
Practical Example: Binary File Operations
Let's create a complete example that demonstrates writing and reading structured data to/from a binary file.
Example: Student Records System
We'll create a program that stores and retrieves student records in binary format.
using System;
using System.IO;
using System.Collections.Generic;
namespace BinaryIOExample
{
    class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double GPA { get; set; }
        public bool IsActive { get; set; }
        public override string ToString()
        {
            return $"Student ID: {Id}, Name: {Name}, GPA: {GPA}, Active: {IsActive}";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "students.bin";
            
            // Create sample student data
            List<Student> students = new List<Student>
            {
                new Student { Id = 1001, Name = "Alice Smith", GPA = 3.8, IsActive = true },
                new Student { Id = 1002, Name = "Bob Johnson", GPA = 3.2, IsActive = true },
                new Student { Id = 1003, Name = "Charlie Brown", GPA = 3.5, IsActive = false }
            };
            // Write students to binary file
            WriteStudentsToBinaryFile(students, filePath);
            // Read students from binary file
            List<Student> loadedStudents = ReadStudentsFromBinaryFile(filePath);
            // Display the loaded students
            Console.WriteLine("Students loaded from binary file:");
            foreach (var student in loadedStudents)
            {
                Console.WriteLine(student);
            }
        }
        static void WriteStudentsToBinaryFile(List<Student> students, string filePath)
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            using (BinaryWriter writer = new BinaryWriter(fs))
            {
                // First write the count of students
                writer.Write(students.Count);
                // Then write each student's data
                foreach (var student in students)
                {
                    writer.Write(student.Id);
                    writer.Write(student.Name);
                    writer.Write(student.GPA);
                    writer.Write(student.IsActive);
                }
            }
            
            Console.WriteLine($"Successfully wrote {students.Count} students to {filePath}");
        }
        static List<Student> ReadStudentsFromBinaryFile(string filePath)
        {
            List<Student> students = new List<Student>();
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            using (BinaryReader reader = new BinaryReader(fs))
            {
                // Read the count of students
                int count = reader.ReadInt32();
                // Read each student
                for (int i = 0; i < count; i++)
                {
                    Student student = new Student
                    {
                        Id = reader.ReadInt32(),
                        Name = reader.ReadString(),
                        GPA = reader.ReadDouble(),
                        IsActive = reader.ReadBoolean()
                    };
                    
                    students.Add(student);
                }
            }
            
            return students;
        }
    }
}
Output:
Successfully wrote 3 students to students.bin
Students loaded from binary file:
Student ID: 1001, Name: Alice Smith, GPA: 3.8, Active: True
Student ID: 1002, Name: Bob Johnson, GPA: 3.2, Active: True
Student ID: 1003, Name: Charlie Brown, GPA: 3.5, Active: False
Real-World Applications
Binary I/O is used in numerous real-world applications:
- File Formats: Creating and reading custom binary file formats
 - Game Development: Saving game state and loading assets
 - Network Communication: Transmitting data efficiently between systems
 - Database Systems: Storing and retrieving data in binary formats
 - Multimedia Applications: Processing audio, video, and image files
 
Best Practices
When working with binary I/O, consider these best practices:
- Always use 
usingstatements for proper resource disposal - Handle exceptions appropriately, especially 
IOException - Consider endianness (byte order) when sharing binary data across systems
 - Document your binary format if creating custom file types
 - Include version information in your binary formats to support future changes
 - Consider compression for large binary files
 
BinaryReader vs. TextReader
| Feature | BinaryReader | TextReader | 
|---|---|---|
| Data Format | Binary data | Text data | 
| Efficiency | More efficient | Less efficient | 
| Types Support | Direct support for primitive types | Strings only (conversions needed) | 
| Use Case | Raw data, structured data | Human-readable text | 
Common Pitfalls
- Not closing streams properly: Can lead to resource leaks
 - Ignoring file format version: Makes it difficult to update file formats
 - Cross-platform issues: Byte ordering differences (endianness)
 - No error checking: Missing proper exception handling
 - Mixing binary and text operations: Can corrupt data
 
Summary
BinaryReader and BinaryWriter are powerful tools in the .NET framework that allow you to efficiently read and write binary data. They provide type-specific methods that simplify working with various data types in their binary representation.
Key takeaways:
- BinaryReader reads primitive data types from a stream
 - BinaryWriter writes primitive data types to a stream
 - Binary I/O is more efficient than text I/O for structured data
 - Always use proper resource disposal with 
usingstatements - Consider the format and compatibility when creating binary files
 
Additional Resources
- Microsoft Documentation: BinaryReader Class
 - Microsoft Documentation: BinaryWriter Class
 - .NET File System and the Registry
 - C# Programming Guide
 
Exercises
- Create a program that saves and loads a list of products (with ID, name, price, and quantity) to a binary file.
 - Extend the student example to include an array of course grades for each student.
 - Create a simple file encryption tool that uses 
BinaryReaderandBinaryWriterto encrypt and decrypt files using a simple XOR cipher. - Implement a program that can merge multiple binary files into one file.
 - Build a binary file viewer that can display the contents of a binary file in both hexadecimal and ASCII formats.
 
Happy coding with binary data in .NET!
💡 Found a typo or mistake? Click "Edit this page" to suggest a correction. Your feedback is greatly appreciated!