C#. Клас Stream. Огляд методів

Клас Stream. Огляд методів. Методи читання з потоку. Приклади


Зміст


Пошук на інших ресурсах:




1. Клас Stream. Операції над потоками

Базовим класом для всіх потоків є абстрактний клас Stream, який визначений у просторі імен System.IO. Клас забезпечує універсальне представлення всіх потоків вводу/виводу. Програміст не заморочується над окремими складовими операційної системи та базових пристроїв вводу/виводу.

У класі Stream визначені властивості та методи, які виконують над потоком наступні операції:

  • читання потоку;
  • запис потоку;
  • пошук в потоці;
  • закриття потоку;
  • скидування потоку;
  • налаштування тайм-ауту;
  • інші операції.

 

2. Операції (методи) читання потоку

Для читання потоку визначені наступні методи та властивості:

  • властивість CanRead – визначає можливість потоку підтримувати читання;
  • метод Read() – читає послідовність байт з поточного потоку;
  • метод ReadByte() – читає один байт з поточного потоку.

 

2.1. Властивість CanRead. Призначення. Загальна форма. Приклад

Властивість CanRead використовується в успадкованих класах для визначення того, чи поточний потік підтримує читання. Загальна форма властивості наступна:

public abstract bool CanRead { get; }

Якщо властивість повертає true, то потік підтримує читання.

Приклад. У прикладі визначається, чи створений файловий потік підтримує читання.

using System;
using System.IO;

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // 1. Створити потік і зв'язати його з файлом "myfile.txt"
      Stream stream;

      using (stream = new FileStream("myfile.txt", FileMode.Create))
      {
        // 2. Властивість CanRead - Визначити, чи потік допускає читання
        if (stream.CanRead)
          Console.WriteLine("Stream supports reading.");
        else
          Console.WriteLine("Stream does not support reading.");

        // 3. Закрити потік
        stream.Close();
      }
    }
  }
}

 

2.2. Метод Read()

Абстрактний метод Read() є базовим у випадках, коли потрібно прочитати послідовність байт з поточного потоку. Метод має декілька реалізацій. Загальна форма найбільш поширеної реалізацї методу наступна

public abstract int Read(byte[] buffer, int offset, int count)

тут

  • buffer – масив заданого розміру, в який зчитуються дані потоку;
  • offset – зміщення (починаючи з 0) в буфері buffer, з якого починається зчитування даних з потоку;
  • count – максимально-можлива кількість байт, що можуть бути зчитані з поточного потоку.

Після читання, позиція в потоці зсувається на кількість прочитаних байт.

Приклад. У прикладі, у файл записується масив рядків типу string[]. Потім цей масив рядок зчитується методом Read().

 

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

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Записати масив рядків у файл
      using (FileStream fw = new FileStream("strings.dat", FileMode.Create, FileAccess.Write))
      {
        // Вихідний масив рядків
        string[] AS = { "abcd", "defgh", "jklmn", "jprst" };
        byte[] AB;

        // Спочатку записати кількість рядків
        AB = BitConverter.GetBytes(AS.Length); // byte[] <= AS.Length
        fw.Write(AB, 0, AB.Length);

        // Записати масив рядків
        for (int i = 0; i < AS.Length; i++)
        {
          // Спочатку записати довжину рядка
          AB = BitConverter.GetBytes(AS[i].Length);
          fw.Write(AB, 0, AB.Length);

          // Потім записати самий рядок
          // byte[] <= string
          AB = Encoding.Default.GetBytes(AS[i]);
          fw.Write(AB, 0, AB.Length);
        }
      }

      // Зчитати з файлу масив рядків
      using (FileStream fr = new FileStream("strings.dat", FileMode.Open, FileAccess.Read))
      {
        // Результуючий масив
        string[] AS2;

        // Допоміжні змінні
        byte[] AB2;

        // Зчитати кількість рядків
        AB2 = new byte[sizeof(int)];
        fr.Read(AB2, 0, AB2.Length); // зчитати з файлу байти
        int count = BitConverter.ToInt32(AB2, 0);
        int len;

        // Виділити пам'ять для масиву рядків
        AS2 = new string[count];

        // Зчитати рядки в циклі
        for (int i = 0; i < AS2.Length; i++)
        {
          // Спочатку зчитати довжину рядка в байтах
          AB2 = new byte[sizeof(int)];
          fr.Read(AB2, 0, AB2.Length);
          len = BitConverter.ToInt32(AB2, 0); // Отримати довжину рядка

          // Зчитати рядок довжиною len байт в буфер AB2
          AB2 = new byte[len]; // виділити пам'ять для буферу
          fr.Read(AB2, 0, len); // зчитати в буфер довжину

          // string <= byte[]
          AS2[i] = "";
          for (int j = 0; j < AB2.Length; j++)
          {
            AS2[i] = AS2[i] + (char)AB2[j];
          }
        }

        // Вивести масив рядків для контролю
        for (int i = 0; i < AS2.Length; i++)
        {
          Console.WriteLine("{0}", AS2[i]);
        }
      }
    }
  }
}

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

abcd
defgh
jklmn
jprst

 

2.3. Метод ReadByte(). Приклад

Метод ReadByte() використовується в успадкованих класах для читання байту з потоку. Після читання поточна позиція читання зсувається на 1 байт. Якщо досягнуто кінець файлу, то повертається -1.

Загальна форма методу наступна

public virtual int ReadByte()

Приклад. Записати число типу int та число типу double у файл. Потім зчитати ці числа.

using System;
using System.IO;

namespace ConsoleApp10
{
  class Program
  {
    static void Main(string[] args)
    {
      // Запис чисел у файл
      using (FileStream fWrite = new FileStream("myfile.bin", FileMode.Create, FileAccess.Write))
      {
        // числа, що потрібно записати
        int num1 = 23;
        double num2 = 3.88;

        // масив байтів, який буде безпосередньо записаний у файл
        byte[] numByte1 = BitConverter.GetBytes(num1);
        byte[] numByte2 = BitConverter.GetBytes(num2);

        // записати числа - метод Write()
        fWrite.Write(numByte1, 0, numByte1.Length);
        fWrite.Write(numByte2, 0, numByte2.Length);
      }

      // Зчитування чисел з файлу
      using (FileStream fRead = new FileStream("myfile.bin", FileMode.Open, FileAccess.Read))
      {
        // Числа, які будуть зчитані з файлу
        int num1;
        double num2;

        // Масиви байт, в які будуть зчитані числа з файлу
        byte[] numByte1 = new byte[sizeof(int)];
        byte[] numByte2 = new byte[sizeof(double)];

        // Прочитати число типу int - використати метод ReadByte()
        for (int i = 0; i < numByte1.Length; i++)
          numByte1[i] = (byte)fRead.ReadByte();

        num1 = BitConverter.ToInt32(numByte1);
        Console.WriteLine("num1 = {0}", num1);

        // Прочитати число типу double
        for (int i = 0; i < numByte2.Length; i++)
          numByte2[i] = (byte)fRead.ReadByte();

        num2 = BitConverter.ToDouble(numByte2);
        Console.WriteLine("num2 = {0}", num2);
      }
    }
  }
}

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

num1 = 23
num2 = 3.88

 


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