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

 


Зв’язані теми