Клас BinaryReader. Робота з файлами у двійковому форматі
Перед вивченням даної теми рекомендується ознайомитись з наступною темою:
Зміст
- 1. Класи BinaryReader та BinaryWriter. Призначення. Загальна інформація
- 2. Взаємодія класу BinaryReader з потоками опорних сховищ. Використання класу FileStream
- 3. Конструктори класу BinaryReader. Створення екземпляру
- 4. Клас BinaryReader. Огляд основних методів
- 4.1. Методи типу Read…() для зчитування даних примітивних типів (int, bool, double, …)
- 4.1.1. Метод ReadBoolean()
- 4.1.2. Методи ReadByte() та ReadBytes()
- 4.1.3. Методи ReadChar() та ReadChars(int)
- 4.1.4. Методи читання даних з плаваючою комою ReadDecimal(), ReadDouble(), ReadSingle()
- 4.1.5. Методи ReadInt16(), ReadInt32(), ReadInt64() читання даних типу int
- 4.1.6. Метод ReadSByte(). Читання даних типу sbyte
- 4.1.7. Метод ReadString(). Читання рядка типу string
- 4.1.8. Методи зчитування даних беззнакового цілого типу
- 4.2. Метод Read()
- 4.3. Метод PeekChar()
- 4.1. Методи типу Read…() для зчитування даних примітивних типів (int, bool, double, …)
- Зв’язані теми
Пошук на інших ресурсах:
1. Класи BinaryReader та BinaryWriter. Призначення. Загальна інформація
Класи BinaryReader та BinaryWriter призначені відповідно для читання та запису даних у двійковому форматі.
Для читання даних примітивних типів та рядків з потоку використовується клас BinaryReader. При читанні можна задати необхідне кодування. За замовчуванням встановлено кодування UTF-8.
Клас BinaryWriter використовується для запису в потік стандартних типів даних та рядків у двійковому форматі. Існує можливість задавання кодування (за замовчуванням UTF-8).
Класи реалізовані в просторі імен System.IO. Для того, щоб використовувати можливості класів BinaryReader, BinaryWriter, потрібно додати рядок
using System.IO;
⇑
2. Взаємодія класу BinaryReader з потоками опорних сховищ. Використання класу FileStream
Як відомо, класи BinaryReader та BinaryWriter відносяться до адаптерів потоків. Безпосередньо взаємодіяти з різними видами сховищ класи не можуть. Для того, щоб доступитись до файлового, мережного чи іншого виду сховища потрібно:
- створити екземпляр відповідного класу як потоку. Це може бути екземпляр одного з чотирьох класів FileStream, IsolatedStorageStream, MemoryStream чи NetworkStream;
- зв’язати створений екземпляр з екземпляром класу BinaryReader або BinaryWriter.
Наприклад. Для того, щоб зчитати інформацію з файлу або записати її у файл потрібно створити екземпляр потоку FileStream (рисунок 1).
Рисунок 1. Взаємодія класу BinaryReader з файлом з допомогою класу FileStream
⇑
3. Конструктори класу BinaryReader. Створення екземпляру
Клас BinaryReader має ряд конструкторів, найбільш вживані з яких наступні:
public BinaryReader(System.IO.Stream input) public BinaryReader(System.IO.Stream input, System.Text.Encoding encoding)
тут
- input – посилання на абстрактний базовий клас Stream;
- encoding – система кодування (Unicode, UTF32, UTF8 та інша). За замовчуванням встановлюється система кодування UTF8.
Приклад. У прикладі продемонстровано створення екземпляру класу BinaryReader з кодуванням за замовчуванням.
... // Створити потік, що зв'язаний з файлом "abc.bin" using (FileStream fs = new FileStream("abc.bin", FileMode.Open)) { // Зв'язати екземпляр BinaryReader з потоком fs using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { ... } }
⇑
4. Клас BinaryReader. Огляд основних методів
Основні методи, що читають дані в класі – це методи, які починаються на префікс Read. Нижче наведено перелік цих методів.
4.1. Методи типу Read…() для зчитування даних примітивних типів (int, bool, double, …)
Для зчитування даних примітивних (стандартних) типів (int, double, char та інші) у двійковому форматі використовується ряд методів. Попередньо ці дані повинні бути записані методом Write(). Нижче подано перелік цих методів.
⇑
4.1.1. Метод ReadBoolean()
Загальна форма методу
public virtual bool ReadBoolean()
Метод зчитує значення типу bool з поточного потоку і зсуває поточну позицію потоку на один байт.
Приклад. Зчитування з файлу значення логічного типу bool. Фрагмент коду передбачає, що це значення попередньо було записане методом Write().
... FileStream fs = new FileStream("file3.bin", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати значення типу bool bool b; b = br.ReadBoolean(); ...
⇑
4.1.2. Методи ReadByte() та ReadBytes()
Метод ReadByte() зчитує з потоку один байт. Метод ReadBytes() зчитує з потоку декілька байт. Загальна форма методів
public virtual byte ReadByte() public virtual byte[] ReadBytes(int count)
тут count – кількість байт, що зчитуються.
Приклад. Наведено приклад зчитування даних методами ReadByte() та ReadBytes().
... FileStream fs = new FileStream("file.dat", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати один байт з файлу "file.dat" byte b = br.ReadByte(); // Зчитати 30 байт з файлу "file.dat" в масив AB byte[] AB = br.ReadBytes(30); ...
⇑
4.1.3. Методи ReadChar() та ReadChars(int)
Методи використовуються для зчитування одиночного символу типу char або декількох символів типу char. Загальна форма методів наступна:
public virtual char ReadChar() public virtual char[] ReadChars(int count)
тут count – кількість символів, які потрібно прочитати з потоку.
Приклад.
... FileStream fs = new FileStream("file.dat", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати один символ char c = br.ReadChar(); // Зчитати 10 символів у масив AC char[] AC = br.ReadChars(10); ...
⇑
4.1.4. Методи читання даних з плаваючою комою ReadDecimal(), ReadDouble(), ReadSingle()
Для читання даних з плаваючою комою використовуються методи ReadDecimal(), ReadDouble(), ReadSingle(), які читають дані типів decimal, double та float відповідно. Загальна форма методів наступна:
public virtual decimal ReadDecimal() public virtual double ReadDouble() public virtual float ReadSingle()
Приклад. У прикладі зчитується масив дійсних чисел з файлу.
... FileStream fs = new FileStream("file.bin", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... float[] AF2; // Зчитати кількість чисел, що записані int count = br.ReadInt32(); // Виділити пам'ять для масиву AF2 = new float[count]; // Цикл зчитування елементів масиву for (int i = 0; i < count; i++) AF2[i] = (float)br.ReadSingle(); // метод ReadSingle ...
⇑
4.1.5. Методи ReadInt16(), ReadInt32(), ReadInt64() читання даних типу int
Для читання даних типу int використовуються наступні методи:
- ReadInt16() – зчитує 2-байтове знакове ціле число з поточного потоку;
- ReadInt32() – зчитує 4-байтове знакове ціле число з потоку;
- ReadInt64() – зчитує 8-байтове знакове ціле число з потоку.
Загальна форма методів наступна
public virtual short ReadInt16() public virtual int ReadInt32() public virtual long ReadInt64()
Приклад.
... FileStream fs = new FileStream("file.bin", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати дані типів short, int, long short s = br.ReadInt16(); int d = br.ReadInt32(); long l = br.ReadInt64(); ...
⇑
4.1.6. Метод ReadSByte(). Читання даних типу sbyte
Метод ReadSByte() зчитує дані типу sbyte. Загальна форма методу:
public virtual sbyte ReadSByte()
Приклад.
... FileStream fs = new FileStream("file.bin", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати дані типу sbyte sbyte sb = br.ReadSByte(); ...
⇑
4.1.7. Метод ReadString(). Читання рядка типу string
Для читання одного рядка з поточного потоку використовується метод ReadString(), який має таку загальну форму:
public virtual string ReadString()
Приклад.
... FileStream fs = new FileStream("file.bin", FileMode.Open); BinaryReader br = new BinaryReader(fs, Encoding.Default); ... // Зчитати дані типу string string s = br.ReadString(); ...
⇑
4.1.8. Методи зчитування даних беззнакового цілого типу
Для зчитування беззнакових цілих типів використовуються методи ReadUint16(), ReadUint32(), ReadUint64(). Загальна форма методів
public virtual ushort ReadUInt16() public virtual uint ReadUInt32() public virtual ulong ReadUInt64()
Приклад.
using (FileStream fs = new FileStream("file3.bin", FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { ... // Зчитати дані типів ushort, uint, ulong ushort us = br.ReadUInt16(); uint ui = br.ReadUInt32(); ulong ul = br.ReadUInt64(); ... } }
⇑
4.2. Метод Read()
Метод Read() має декілька перевантажених реалізацій. Нижче наведено загальну форму найбільш вживаних реалізацій методу. Перша реалізація методу не містить параметрів
public virtual int Read()
При такій реалізації зчитуються символи з базового потоку і переміщується поточна позиція потоку вперед у відповідності з використовуваним кодуванням. Метод повертає наступний символ з потоку вводу.
Наступні реалізації
public virtual int Read(byte[] buffer, int index, int count) public virtual int Read(char[] buffer, int index, int count)
зчитують відповідно визначене число байт чи символів з потоку, починаючи з визначеного потоку в масиві байт.
Приклад.
У прикладі демонструється використання методу Read(), який зчитує масив байт типу byte[]. Спочатку у файл записується масив типу double[]. Потім цей масив зчитується методом Read(byte[], int, int).
Приклад також демонструє можливості класу BitConverter, який призначений для конвертування різних типів у тип byte[] і, навпаки. Демонструється конвертування чисел масиву double[] в масив byte[].
Текст програми наступний.
using System; using System.IO; using System.Text; namespace ConsoleApp10 { class Program { static void Main(string[] args) { // Записати у файл file3.bin масив чисел типу double[] // 1. Запис чисел using (FileStream fs = new FileStream("file3.bin", FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { // 1.1. Дані, що записуються double[] AD = { 2.8, 3.3, 1.4 }; // 1.2. Допоміжний масив byte[] B; // 1.3. Записати кількість чисел bw.Write(AD.Length); // 1.4. Цикл запису чисел в файл for (int i = 0; i < AD.Length; i++) { // Конвертувати double => byte[] B = BitConverter.GetBytes(AD[i]); // Записати масив byte[] у файл bw.Write(B, 0, B.Length); } } } // 2. Зчитування з файлу масиву чисел типу double[] using (FileStream fs = new FileStream("file3.bin", FileMode.Open)) { using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { // 2.1. Допоміжні змінні double[] AD2; // Масив-результат byte[] B2 = new byte[sizeof(double)]; // виділити пам'ять для буферу // 2.2. Зчитати кількість чисел, що записані у файлі int count = br.ReadInt32(); AD2 = new double[count]; // виділити пам'ять // 2.3. Зчитати числа у масив AD2 for (int i = 0; i < AD2.Length; i++) { br.Read(B2, 0, sizeof(double)); AD2[i] = BitConverter.ToDouble(B2, 0); } // 2.4. Вивести масив AD2 для контролю Console.Write("AD2 = { "); for (int i = 0; i < AD2.Length; i++) Console.Write(AD2[i] + " "); Console.WriteLine("}"); } } } } }
Результат роботи програми
AD2 = { 2.8 3.3 1.4 }
⇑
4.3. Метод PeekChar()
Метод PeekChar() отримує наступний наявний символ без приросту позиції байту чи символу.
public virtual int PeekChar()
Якщо неможливо прочитати символ (наприклад, кінець файлу), то метод повертає -1.
Приклад. У прикладі в файл записується рядок, потім цей рядок зчитується посимвольно. Для визначення того, чи можна прочитати символ використовується метод PeekChar().
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.1. Дані, що записуються string s = "Hello world!"; // 1.2. Записати рядок посимвольно char[] cc = s.ToCharArray(); for (int i = 0; i < s.Length; i++) { bw.Write(s[i]); } } } // 2. Зчитування з файлу масиву чисел типу float using (FileStream fs = new FileStream("file3.bin", FileMode.Open)) { using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { // Зчитати рядок посимвольно char c; // Читання посимвольно, поки можна прочитати while (br.PeekChar()!=-1) { c = br.ReadChar(); Console.Write(c); } } } } } }
⇑
Зв’язані теми
- Клас BinaryWriter. Робота з бінарними файлами
- Приклади розв’язування задач на обробку файлів у двійковому (бінарному) форматі з використанням класів BinaryReader та BinaryWriter
⇑