C#. Классы BinaryReader, BinaryWriter. Примеры решения задач

Классы BinaryReader, BinaryWriter. Примеры решения задач на чтение из файлов и запись в файлы данных в двоичном формате


Содержание


Поиск на других ресурсах:




1. Запись в файл и считывание из файла чисел различных форматов (double, char, string, sbyte). Пример

В примере продемонстрирована запись в файл file2.bin и считывание из него следующих данных:

  • числа типа double;
  • строки типа string;
  • символа типа char;
  • числа типа sbyte.

 

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

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Записать в файл file2.bin следующие данные:
      // - число типа double;
      // - строку типа string;
      // - символ типа char;
      // - число типа sbyte.

      // 1. Запись чисел
      using (FileStream fs = new FileStream("file2.bin",
FileMode.Create))
      {
        using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
        {
          // 1.2. Исходные числа
          double x = 3.88;
          string s = "Hello world!";
          char c = 'Z';
          sbyte b = 17;

          // 1.3. Запись чисел - метод Write()
          bw.Write(x);
          bw.Write(s);
          bw.Write(c);
          bw.Write(b);
        }
      }

      // 2. Чтение чисел
      using (FileStream fs = new FileStream("file2.bin",
FileMode.Open))
      {
        using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
        {
          // 2.1. Переменные, в которые считываются данные
          double x2;
          string s2;
          char c2;
          sbyte b2;

          // 2.2. Считывание данных
          x2 = br.ReadDouble();
          s2 = br.ReadString();
          c2 = br.ReadChar();
          b2 = br.ReadSByte();

          // 2.3. Вывод результата для контроля
          Console.WriteLine("x2 = {0}", x2);
          Console.WriteLine("s2 = {0}", s2);
          Console.WriteLine("c2 = {0}", c2);
          Console.WriteLine("b2 = {0}", b2);
        }
      }
    }
  }
}

Результат выполнения программы

x2 = 3.88
s2 = Hello world!
c2 = Z
b2 = 17

 

2. Запись в файл и считывание из файла массива чисел типа float[]. Пример

Чтобы записать любой массив нужно придерживаться следующей последовательности действий:

  1. Записать количество элементов в массиве.
  2. В цикле записать элементы массива.

При считывании массива нужно придерживаться такой же последовательности действий:

  1. Считать количество элементов в массиве.
  2. При помощи оператора цикла считать элементы массива.

 

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

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Записать в файл file3.bin массив чисел типа float[]
      // 1. Запись чисел
      using (FileStream fs = new FileStream("file3.bin", FileMode.Create))
      {
        using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
        {
          // 1.2. Исходный массив
          float[] AF = { 2.1f, 3.8f, 4.4f, -2.3f, -1.3f };

          // 1.3. Запись массива
          // Сначала записать количество чисел
          bw.Write(AF.Length);

          // Цикл записи элементов массива
          for (int i = 0; i < AF.Length; i++)
            bw.Write((double)AF[i]); // записываются как double
        }
      }

      // 2. Считывание из файла массива чисел типа float
      using (FileStream fs = new FileStream("file3.bin", FileMode.Open))
      {
        using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
        {
          // 2.1. Массив-результат
          float[] AF2;

          // 2.2. Считать количество записанных чисел
          int count = br.ReadInt32();
          AF2 = new float[count];

          // 2.3. Прочитать массив
          for (int i = 0; i < count; i++)
            AF2[i] = (float)br.ReadDouble(); // считываются как double

          // 2.3. Вывод результата для контроля
          Console.Write("AF2 = { ");
          for (int i = 0; i < AF2.Length; i++)
            Console.Write(AF2[i] + " ");
          Console.WriteLine(" }");
        }
      }
    }
  }
}

Результат выполнения программы

AF2 = { 2.1 3.8 4.4 -2.3 -1.3 }

 

3. Демонстрационная программа записи массива строк (string[]) в файл и его считывание из файла. Пример.

Условие задачи. Разработать класс с именем ReadWriteArrayOfStrings, который содержит два метода:

  • метод WriteArrayStr() — записывает массив строк в файл;
  • метод ReadArrayStr() — считывает из файла строки в массив.

Для записи в файл использовать класс BinaryWriter. Для чтения из файла использовать класс BinaryReader.
Протестировать работу класса.

Решение. Поскольку классы BinaryWriter и BinaryReader являются адаптерами потоков, то для того, чтобы непосредственно получить доступ к файлу, нужно использовать соответствующий класс из опорного хранилища. Для доступа к файлам используется класс FileStream.

using System;
using System.IO;

namespace ConsoleApp10
{
  // Класс, содержащий методы записи/чтения массива строк в байтовый поток.
  class ReadWriteArrayOfStrings
  {
    // Метод, который записывает массив строк в файл.
    // Параметры метода:
    // - AS - массив строк;
    // - filename - имя файла.
    public void WriteArrayStr(string[] AS, string filename)
    {
      // 1. Создать поток и связать его с файлом filename
      // Директива using обеспечивает автоматическую очистку ресурсов.
      using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
      {
        // 2. Связать поток fs с экземпляром bw:
        // bw -> fs -> filename
        BinaryWriter bw = new BinaryWriter(fs);

        // 3. Записать количество строк в файл
        bw.Write(AS.Length);

        // 4. Цикл записи массива строк в файл
        for (int i = 0; i < AS.Length; i++)
        {
          bw.Write(AS[i]);
        }
      }
    }

    // Метод, читающий строки из файла
    public string[] ReadArrayStr(string filename)
    {
      // Попытка открыть файл для чтения
      using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
      {
        // Связать экземпляр br з fs:
        // br <- fs <- filename
        BinaryReader br = new BinaryReader(fs);

        // Прочитать количество элементов в массиве строк
        int count = br.ReadInt32();

        // Объявить массив строк и выделить для него память
        string[] AS = new string[count];

        // Прочитать строки в массив AS
        for (int i=0; i<AS.Length; i++)
        {
          // Прочитать строку
          AS[i] = br.ReadString();
        }

        // Вернуть результат
        return AS;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Тестирование работы класса ReadWriteArrayOfStrings

      // 1. Создать экземпляр класса
      ReadWriteArrayOfStrings obj = new ReadWriteArrayOfStrings();

      // 2. Объявить тестируемый массив строк
      string[] AS = { "abc", "def", "ghi", "jklmn", "jprst" };

      // 3. Вызвать метод записи строк в файл "myfile.bin"
      obj.WriteArrayStr(AS, "myfile.bin");

      // 4. Считать строки в другой массив из того же файла
      string[] AS2 = obj.ReadArrayStr("myfile.bin");

      // 5. Вывести прочитанные строки
      Console.WriteLine("Array AS2:");
      foreach (string s in AS2)
        Console.WriteLine(s);
    }
  }
}

Результат выполнения программы

Array AS2:
abc
def
ghi
jklmn
jprst

После выполнения, будет создан файл с именем «myfile.bin».

 

4. Пример записи/чтения массива экземпляров класса Worker (Служащий)

Условие задачи. Задан класс Worker, который реализует работника. Класс содержит следующие внутренние поля:

  • имя работника;
  • пол;
  • возраст;
  • рейтинг.

В программе нужно последовательно выполнить следующие операции:

  • создать массив экземпляров класса Worker;
  • записать этот массив в файл «workers.bin» в двоичном формате;
  • считать данные из файла «workers.bin» в другой массив;
  • вывести полученный массив на экран для контроля.

Решение. Чтобы получить доступ к файловому хранилищу используется класс FileStream.
Для записи в файл в двоичном формате используется метод Write() класса BinaryWriter. Для считывания файла в двоичном формате используются следующие методы класса BinaryReader:

  • ReadInt32() — считывает число типа int из файлового потока;
  • ReadDouble() — считывает число типа double;
  • ReadChar() — считывает символ типа char;
  • ReadString() — считывает строку символов.

Текст программы решения задачи следующий.

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

namespace ConsoleApp10
{
  // Класс, реализующий работника
  class Worker
  {
    // Поля класса
    private string name; // Фамилия, имя работника
    private char gender; // пол
    private int age; // возраст в годах
    private double rank; // рейтинг

    // Конструктор
    public Worker(string name, char gender, int age, double rank)
    {
      this.name = name;
      this.gender = gender;
      this.age = age;
      this.rank = rank;
    }

    // Свойства доступа к полям класса
    public string Name
    {
      get { return name; }
      set { name = value; }
    }

    public char Gender
    {
      get { return gender; }
      set { gender = value; }
    }

    public int Age
    {
      get { return age; }
      set { age = value; }
    }

    public double Rank
    {
      get { return rank; }
      set { rank = value; }
    }

    // Метод вывода данных текущего экземпляра
    public void Print(string text)
    {
      Console.Write(text + " ");
      Console.Write("name = {0}, gender = {1}, age = {2}, rank = {3}",
                    name, gender, age, rank);
      Console.WriteLine();
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Записать в файл "workers.bin" массив экземпляров типа Worker
      // 1. Запись массива экземпляров
      using (FileStream fs = new FileStream("workers.bin",
FileMode.Create))
      {
        using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default))
        {
          // 1.1. Создать четырех работников - это есть записываемые данные
          Worker[] AW = {
            new Worker("Johnson J.", 'M', 42, 4.45),
            new Worker("Johansson S.", 'F', 33, 4.77),
            new Worker("Shcherbyuk I.", 'M', 49, 4.99),
            new Worker("Ivanov I.", 'M', 39, 4.8)
          };

          // 1.2. Запись массива AW в файл
          // 1.2.1. Сначала записать количество работников
          bw.Write(AW.Length);

          // 1.2.2. Затем в цикле записать каждого работника
          foreach (Worker w in AW)
          {
            // Имя работника
            bw.Write(w.Name);

            // Пол
            bw.Write(w.Gender);

            // Возраст
            bw.Write(w.Age);

            // Рейтинг
            bw.Write(w.Rank);
          }
        }
      }

      // 2. Считывание массива типа Worker из файла "workers.bin"
      using (FileStream fs = new FileStream("workers.bin", FileMode.Open))
      {
        using (BinaryReader br = new BinaryReader(fs, Encoding.Default))
        {
          // 2.1. Объявить массив, в который будут сохранены данные из файла,
          // а также дополнительные переменные
          Worker[] AW2;
          string name;
          char gender;
          int age;
          double rank;
          string s; // вспомогательная строка

          // 2.2. Прочитать количество сохраненных экземпляров
          // и выделить для них память
          AW2 = new Worker[br.ReadInt32()];

          // 2.3. Считать экземпляры класса Worker в массив AW2
          for (int i = 0; i < AW2.Length; i++)
          {
            // Прочитать имя
            name = br.ReadString();

            // прочитать пол
            gender = br.ReadChar();

            // прочитать возраст
            age = br.ReadInt32();

            // прочитать рейтинг
            rank = br.ReadDouble();

            // Выделить память для AW2[i] и создать экземпляр
            AW2[i] = new Worker(name, gender, age, rank);
          }

          // 2.4. Вывести информацию о прочитанных экземплярах класса Worker
          for (int i = 0; i < AW2.Length; i++)
          {
            // сформировать строку
            s = "AW2[" + Convert.ToString(i) + "]: ";

            // распечатать данные экземпляра
            AW2[i].Print(s);
          }
        }
      }
    }
  }
}

Результат выполнения программы

AW2[0]: name = Johnson J., gender = M, age = 42, rank = 4.45
AW2[1]: name = Johansson S., gender = F, age = 33, rank = 4.77
AW2[2]: name = Shcherbyuk I., gender = M, age = 49, rank = 4.99
AW2[3]: name = Ivanov I., gender = M, age = 39, rank = 4.8

 


Связанные темы