C#. The BinaryReader class. Working with files




The BinaryReader class. Working with binary files

It is recommended that you familiarize yourself with the following topics before exploring this topic:


Contents


Search other websites:

1. BinaryReader and BinaryWriter classes. The purpose. General information

The BinaryReader and BinaryWriter classes are designed to read and write data in binary format, respectively.

The BinaryReader class is used to read primitive data and strings from the stream. When reading, you can specify the required encoding. The default is UTF-8 encoding.
The BinaryWriter class is used to write standard data types and binary strings to a stream. It is possible to specify the encoding (UTF-8 by default).
The classes are implemented in the System.IO namespace. In order to use the capabilities of the BinaryReader, BinaryWriter classes, you need to include System.IO

using System.IO;

 

2. Interaction of the BinaryReader class with basic store streams. Using the FileStream class

As you know, the BinaryReader and BinaryWriter classes are stream adapters. Classes cannot directly interact with different types of storage. In order to go to file, network or other type of storage you need:

  • instantiate the corresponding class as a thread. It can be an instance of one of the four classes: FileStream, IsolatedStorageStream, MemoryStream or NetworkStream;
  • associate the created instance with an instance of the BinaryReader or BinaryWriter class.

For example. In order to read information from a file or write it to a file, you need to create an instance of the FileStream stream (Figure 1).

C#. The interaction of BinaryReader class with the file, using the FileStream class

Figure 1. The interaction of BinaryReader class with the file, using the FileStream class

 

3. Constructors of BinaryReader class. Creating an instance

The BinaryReader class has several constructors, the most commonly used of which are:

public BinaryReader(System.IO.Stream input)
public BinaryReader(System.IO.Stream input, System.Text.Encoding encoding)

here

  • input – a reference to the abstract base class Stream;
  • encoding – encoding system (Unicode, UTF32, UTF8 and others). The default encoding system is UTF8.

Example. encoding system (Unicode, UTF32, UTF8 and others). The default encoding system is UTF8.

...
// Create a stream that is associated with the file "abc.bin"
using (FileStream fs = new FileStream("abc.bin",
       FileMode.Open))
{
    // Bind the BinaryReader instance to the fs stream
    using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
    {
        ...
    }
}

 

4. The BinaryReader class. Overview of basic methods

The main methods that read data in a class are methods that start with the Read prefix. The following is a list of these methods.

4.1. Methods of type Read… () for reading data of primitive types (int, bool, double, …)

A number of methods are used to read data of primitive (standard) types (int, double, char and others) in binary format. Previously, this data must be written using the Write() method.
Below is a list of these methods.

4.1.1. Method ReadBoolean()

General form of the method is as follows

public virtual bool ReadBoolean()

The method reads a bool value from the current stream and shifts the current position by one byte.

Example. Reading a boolean value from a file. The code snippet assumes that this value was previously written with the Write() method.

...

FileStream fs = new FileStream("file3.bin", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read the value of bool type
bool b;
b = br.ReadBoolean();

...

 

4.1.2. Methods ReadByte() and ReadBytes()

The ReadByte() method reads one byte from the stream. The ReadBytes() method reads several bytes from the stream. General form of methods

public virtual byte ReadByte()
public virtual byte[] ReadBytes(int count)

here count is the number of bytes read.

Example. An example of data reading by the ReadByte() and ReadBytes() methods is given.

...
FileStream fs = new FileStream("file.dat", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read one byte from file "file.dat"
byte b = br.ReadByte();

// Read 30 bytes from file "file.dat" into array AB
byte[] AB = br.ReadBytes(30);

...

 

4.1.3. Methods ReadChar() and ReadChars(int)

Methods are used to read a single char or multiple char characters. The general form of the methods is as follows:

public virtual char ReadChar()
public virtual char[] ReadChars(int count)

here count – the number of characters to read from the stream.

Example.

...

FileStream fs = new FileStream("file.dat", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read a single character
char c = br.ReadChar();

// Read 10 characters into AC array
char[] AC = br.ReadChars(10);

...

 

4.1.4. Floating point data reading methods ReadDecimal(), ReadDouble(), ReadSingle()

To read floating-point data, the ReadDecimal(), ReadDouble(), ReadSingle() methods are used, which read data of the decimal, double and float types, respectively. The general form of the methods is as follows:

public virtual decimal ReadDecimal()
public virtual double ReadDouble()
public virtual float ReadSingle()

Example. The example reads an array of real numbers from a file.

...

FileStream fs = new FileStream("file.bin", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

float[] AF2;

// Read the number of written numbers
int count = br.ReadInt32();

// Allocate memory for array
AF2 = new float[count];

// Loop for reading array elements
for (int i = 0; i < count; i++)
  AF2[i] = (float)br.ReadSingle(); // method ReadSingle()

...

 

4.1.5. ReadInt16(), ReadInt32(), ReadInt64() methods for reading int data

The following methods are used to read data of type int:

  • ReadInt16() – reads a 2-byte signed integer from the current stream;
  • ReadInt32() – reads a 4-byte signed integer from the stream;
  • ReadInt64() – Reads an 8-byte signed integer from the stream.

The general form of the methods is as follows

public virtual short ReadInt16()
public virtual int ReadInt32()
public virtual long ReadInt64()

Example.

...

FileStream fs = new FileStream("file.bin", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read data of types short, int, long
short s = br.ReadInt16();
int d = br.ReadInt32();
long l = br.ReadInt64();

...

 

4.1.6. Method ReadSByte(). Read data of sbyte type

The ReadSByte() method reads data of type sbyte. General form of the method:

public virtual sbyte ReadSByte()

Example.

...

FileStream fs = new FileStream("file.bin", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read data of sbyte type
sbyte sb = br.ReadSByte();

...

 

4.1.7. Method ReadString(). Read a string

To read a single line from the current stream, the ReadString () method is used, which has the following general form:

public virtual string ReadString()

Example.

...

FileStream fs = new FileStream("file.bin", FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default);

...

// Read data of string type
string s = br.ReadString();

...

 

4.1.8. Methods for reading unsigned integer data ReadUint16(), ReadUint32(), ReadUint64()

To read unsigned integer types, use the ReadUint16(), ReadUint32(), ReadUint64() methods. General form of methods is as follows

public virtual ushort ReadUInt16()
public virtual uint ReadUInt32()
public virtual ulong ReadUInt64()

Example.

using (FileStream fs = new FileStream("file3.bin",
        FileMode.Create))
{
    using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
    {
        ...

        // Read data of types ushort, uint, ulong
        ushort us = br.ReadUInt16();
        uint ui = br.ReadUInt32();
        ulong ul = br.ReadUInt64();

        ...
    }
}

 

4.2. Method Read()

The Read() method has several overloaded implementations. Below is a general form of the most commonly used method implementations. The first implementation of the method contains no parameters

public virtual int Read()

This implementation reads characters from the base stream and moves the current stream position forward in accordance with the encoding used. The method returns the next character from the input stream.
The following implementations

public virtual int Read(byte[] buffer, int index, int count)
public virtual int Read(char[] buffer, int index, int count)

read, respectively, a specified number of bytes or characters from a stream, starting with a specified stream in the byte array.

Example.

The example demonstrates the use of the Read() method, which reads an array of bytes of type byte[]. First, an array of type double[] is written to the file. Then this array is read by the Read (byte[], int, int) method.

The example also demonstrates the capabilities of the BitConverter class, which is designed to convert various types to byte[] and vice versa. Demonstrates converting numbers from the double[] array to the byte[] array.

The program text is as follows.

using System;
using System.IO;
using System.Text;

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Write an array of double[] numbers to the "file3.bin" file
      // 1. Write numbers
      using (FileStream fs = new FileStream("file3.bin",
             FileMode.Create))
      {
        using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
        {
          // 1.1. Write an array of double[] numbers to the file file3.bin
          double[] AD = { 2.8, 3.3, 1.4 };

          // 1.2. Additional array
          byte[] B;

          // 1.3. Write the number of numbers
          bw.Write(AD.Length);

          // 1.4. Cycle for writing numbers to a file
          for (int i = 0; i < AD.Length; i++)
          {
            // Converting double => byte[]
            B = BitConverter.GetBytes(AD[i]);

            // Write array byte[] to file
            bw.Write(B, 0, B.Length);
          }
        }
      }

      // 2. Reading an array of double[] from file
      using (FileStream fs = new FileStream("file3.bin", FileMode.Open))
      {
        using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
        {
          // 2.1. Additional variables
          double[] AD2; // The resulting array
          byte[] B2 = new byte[sizeof(double)]; // allocate memory for buffer

          // 2.2. Read the number of numbers written in the file
          int count = br.ReadInt32();
          AD2 = new double[count]; // allocate memory

          // 2.3. Read numbers to AD2 array
          for (int i = 0; i < AD2.Length; i++)
          {
            br.Read(B2, 0, sizeof(double));
            AD2[i] = BitConverter.ToDouble(B2, 0);
          }

          // 2.4. Display AD2 array
          Console.Write("AD2 = { ");
          for (int i = 0; i < AD2.Length; i++)
            Console.Write(AD2[i] + " ");
          Console.WriteLine("}");
        }
      }
    }
  }
}

The result of the program

AD2 = { 2.8 3.3 1.4 }

 

4.3. The PeekChar() method

The PeekChar() method gets the next available character without incrementing the byte or character position

public virtual int PeekChar()

If it is impossible to read a character (for example, end of file), then the method returns -1.

Example. In the example, a line is written to the file, then this line is read character by character. The PeekChar() method is used to determine if a character can be read.

using System;
using System.IO;
using System.Text;

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Write an array of float[] numbers to the file file3.bin
      // 1. Write numbers
      using (FileStream fs = new FileStream("file3.bin",
              FileMode.Create))
      {
        using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
        {
          // 1.1. Written data
          string s = "Hello world!";

          // 1.2. Write string character by character
          char[] cc = s.ToCharArray();

          for (int i = 0; i < s.Length; i++)
          {
            bw.Write(s[i]);
          }
        }
      }

      // 2. Reading an array of floats from a file
      using (FileStream fs = new FileStream("file3.bin", FileMode.Open))
      {
        using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
        {
          // Read line character by character
          char c;

          // Reading character by character while you can read
          while (br.PeekChar()!=-1)
          {
            c = br.ReadChar();
            Console.Write(c);
          }
        }
      }
    }
  }
}

 


Related topics