BinaryReader in C# is a class that enables reading primitive data types (like integers, floats, strings) from a binary stream.
It’s commonly used for reading data written by BinaryWriter and provides methods for reading various types in a specific encoding.
BinaryReader is part of the System.IO namespace and works well with FileStream or other binary streams.
In this tutorial, we’ll cover:
1. Basics of BinaryReader
BinaryReader reads data from a binary stream in a specific encoding. It reads each data type in its binary format, making it efficient for file I/O and network operations.
Syntax for Basic BinaryReader Setup:
using System.IO; using (BinaryReader reader = new BinaryReader(new FileStream("file.bin", FileMode.Open))) { // Reading code goes here }
The using statement ensures that the BinaryReader object is closed automatically after use, releasing any resources.
2. Reading Primitive Data Types with BinaryReader
BinaryReader provides methods to read various primitive data types, such as ReadInt32(), ReadSingle(), ReadBoolean(), etc., which read binary data and convert it to the respective type.
Example: Reading Primitive Data Types
using System; using System.IO; public class BinaryReaderExample { public static void Main() { using (BinaryWriter writer = new BinaryWriter(new FileStream("data.bin", FileMode.Create))) { writer.Write(42); // Write an integer writer.Write(3.14f); // Write a float writer.Write(true); // Write a boolean writer.Write(123.456); // Write a double } using (BinaryReader reader = new BinaryReader(new FileStream("data.bin", FileMode.Open))) { int intValue = reader.ReadInt32(); float floatValue = reader.ReadSingle(); bool boolValue = reader.ReadBoolean(); double doubleValue = reader.ReadDouble(); Console.WriteLine("Integer: " + intValue); Console.WriteLine("Float: " + floatValue); Console.WriteLine("Boolean: " + boolValue); Console.WriteLine("Double: " + doubleValue); } } }
Explanation:
- The BinaryWriter writes an integer, float, boolean, and double to data.bin in binary format.
- The BinaryReader reads these values back in the same order, using ReadInt32(), ReadSingle(), ReadBoolean(), and ReadDouble() methods.
Output:
Integer: 42 Float: 3.14 Boolean: True Double: 123.456
3. Reading Strings and Other Complex Data with BinaryReader
BinaryReader can read strings written by BinaryWriter using the ReadString() method. This method reads the string in binary format.
Example: Writing and Reading Strings in Binary Format
using System; using System.IO; public class BinaryReaderStringExample { public static void Main() { // Writing a string to a binary file using (BinaryWriter writer = new BinaryWriter(new FileStream("stringData.bin", FileMode.Create))) { writer.Write("Hello, BinaryReader!"); writer.Write("Another line of text."); } // Reading the strings back from the binary file using (BinaryReader reader = new BinaryReader(new FileStream("stringData.bin", FileMode.Open))) { string message1 = reader.ReadString(); string message2 = reader.ReadString(); Console.WriteLine("Read from binary file:"); Console.WriteLine(message1); Console.WriteLine(message2); } } }
Explanation:
- BinaryWriter writes strings to stringData.bin using Write(string).
- BinaryReader reads them back with ReadString(), in the same order.
Output:
Read from binary file: Hello, BinaryReader! Another line of text.
4. Using BinaryReader with FileStream
You can use BinaryReader with FileStream to read a sequence of numbers or other data structures stored in binary format.
Example: Reading a List of Integers from a Binary File
using System; using System.IO; public class BinaryFileStreamExample { public static void Main() { int[] numbers = { 10, 20, 30, 40, 50 }; using (BinaryWriter writer = new BinaryWriter(new FileStream("numbers.bin", FileMode.Create))) { foreach (int number in numbers) { writer.Write(number); } } using (BinaryReader reader = new BinaryReader(new FileStream("numbers.bin", FileMode.Open))) { Console.WriteLine("Reading integers from binary file:"); while (reader.BaseStream.Position != reader.BaseStream.Length) { Console.WriteLine(reader.ReadInt32()); } } } }
Explanation:
- BinaryWriter writes each integer from numbers to numbers.bin.
- BinaryReader reads each integer from the file in the same order using a while loop.
Output:
Reading integers from binary file: 10 20 30 40 50
5. Practical Example: Loading Structured Data with BinaryReader
In this example, we’ll load a list of structured data (e.g., student records) from a binary file that was saved using BinaryWriter.
Example: Loading Student Records
using System; using System.IO; public class Student { public int ID { get; set; } public string Name { get; set; } public double GPA { get; set; } } public class StudentDataBinaryExample { public static void SaveStudentData(Student[] students, string filePath) { using (BinaryWriter writer = new BinaryWriter(new FileStream(filePath, FileMode.Create))) { writer.Write(students.Length); // Write the number of students foreach (var student in students) { writer.Write(student.ID); writer.Write(student.Name); writer.Write(student.GPA); } } } public static void LoadStudentData(string filePath) { using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) { int studentCount = reader.ReadInt32(); // Read the number of students Console.WriteLine($"Number of students: {studentCount}"); for (int i = 0; i < studentCount; i++) { int id = reader.ReadInt32(); string name = reader.ReadString(); double gpa = reader.ReadDouble(); Console.WriteLine($"ID: {id}, Name: {name}, GPA: {gpa}"); } } } public static void Main() { Student[] students = new Student[] { new Student { ID = 1, Name = "Alice", GPA = 3.5 }, new Student { ID = 2, Name = "Bob", GPA = 3.8 }, new Student { ID = 3, Name = "Charlie", GPA = 3.2 } }; string filePath = "students.bin"; SaveStudentData(students, filePath); LoadStudentData(filePath); } }
Explanation:
- SaveStudentData() writes each student’s data to students.bin in binary format.
- LoadStudentData() reads the binary file back and displays each student’s details.
- ReadInt32(), ReadString(), and ReadDouble() read each field in the same order as they were written, preserving the data’s structure.
Output:
Number of students: 3 ID: 1, Name: Alice, GPA: 3.5 ID: 2, Name: Bob, GPA: 3.8 ID: 3, Name: Charlie, GPA: 3.2
Summary
BinaryReader in C# provides an efficient way to read primitive data types and structured data from binary files, making it ideal for compact and optimized data storage and retrieval. Here’s a summary of the key points:
- Basic Setup: BinaryReader works with FileStream to read data in binary format.
- Reading Primitive Types: BinaryReader has methods like ReadInt32(), ReadSingle(), ReadBoolean(), ReadDouble() to read primitive types efficiently.
- Reading Strings: ReadString() allows for reading strings written in binary format.
- FileStream: Use BinaryReader with FileStream to manage the file’s opening, reading, and closing.
- Structured Data: Load structured data (e.g., student records) in binary format for optimized data storage.
BinaryReader is useful for applications requiring compact, high-performance binary data storage and retrieval, especially when paired with BinaryWriter.