Stream C#

Stream C#

Всем доброго времени суток. На связи Алексей Гулынин. В данной статье я бы хотел рассказать про потоки (Stream) в C#. Чтобы лучше понять, что такое поток представим себе трубу с двумя концами, через которую последовательно двигаются байты. На уровне операционной системы файлы имеют байтовую организацию. Данные в поток можно записывать и можно их читать. Потоки подразделяются на несколько типов:

  1. Файловый поток (FileStream),
  2. Сетевой поток (NetworkStream),
  3. Поток в памяти (MemoryStream)

Также существует базовый абстрактный класс "Stream", от которого наследуются все классы потоков. Потоки работают только с байтами. Методы "Read()" и "Write()" принимают в качестве параметров либо байты, либо массивы байтов. Это бывает неудобно в случае, например, когда нужно в потоке записывать данные в текстовый файл. Неудобство заключается в том, что все строки нужно преобразовывать из кодировки "UTF-16" (стандарт для строк) в кодировку этого файла и записывать их.

Также неудобство заключается в чтении такого потока. Например, мы хотим построчно читать текстовый файл. В данном случае, построчного чтения строк в потоке, как такого нет, есть побайтовое чтение. Здесь мы будем читать байты до тех пор, пока не дойдём до байта с кодом переноса строки или конца файла. Причем эти все байты нужно где-то хранить (организовывать буфер).

Кроме понятия потоков ввели понятия "Reader" и "Writer". Если поток рассматривать, как трубу, то "Reader" и "Writer" — это переходники, которые ставятся на конец этой трубы. Есть 2 трубы разного диаметра, как разного типа данных. "Reader" и "Writer" позволяют осуществлять преобразование типов.

Есть поток, который принимает в себя последовательность байтов. Нам нужно в этот поток записать строки. В данном случае можем использовать класс "StreamWriter". В данном классе происходит автоматическое преобразование строки в последовательность байтов.

Класс "StreamReader" используется для того, чтобы читать строки побайтово, при этом происходит автоматическое преобразование из последовательности байтов в строку, удобную для чтения.

Давайте на примере файлового потока рассмотрим, как этот механизм работает.

static void Main(string[] args)
{
  // задаём путь до файла
  string pathToFile = @"C:\test.txt";
  // создаём Writer
  // true - данные будут записываться в файл, не затирая его
  StreamWriter sw = new StreamWriter(pathToFile, true);
  // записываем данные в поток
  sw.WriteLine("new string");
  // не забываем закрывать поток
  sw.Close();
  Console.ReadLine();
}

В данном примере мы напрямую не создавали объект класса "FileStream", но это не говорит о том, что он не создался. Когда мы создаём объект "StreamWriter" в конструкторе автоматически создаётся поток (в данном случае объект класса "FileStream"). Командой "sw.Close()" мы закрываем именно "FileStream".

Давайте на примере разберем, как прочитать данные из потока:

static void Main(string[] args)
{
  // задаём путь до файла
  string pathToFile = @"C:\test.txt";
  // создаём Reader
  StreamReader sr = new StreamReader(pathToFile);
  // читаем файл полностью
  Console.WriteLine(sr.ReadToEnd());
  // после этого у нас указатель будет на последнем байте потока
  // sr.EndOfStream будет равно true
  // нужно вернуть указатель на начало
  sr.BaseStream.Position = 0;
  Console.WriteLine("---------------");
  // читаем файл построчно
  string line = "";
  int i = 0;
  while ((line = sr.ReadLine()) != null)
  {
    Console.WriteLine("{0}. {1}", i, line);
    i++;
  }
  sr.Close();
  Console.ReadLine();
}

В данной статье вы узнали, что такое Stream в C#.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *