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

 


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