Класс Stream

22

Основным для потоков является класс System.IO.Stream. Он представляет байтовый поток и является базовым для всех остальных классов потоков. Кроме того, он является абстрактным классом, а это означает, что получить экземпляр объекта класса Stream нельзя.

В абстрактном классе System.IO.Stream определен набор членов, которые обеспечивают поддержку синхронного и асинхронного взаимодействия с хранилищем (например, файлом или областью памяти).

Концепция потока не ограничена файловым вводом-выводом. Точности ради следует отметить, что библиотеки .NET предоставляют потоковый доступ к сетям, областям памяти и прочим абстракциям, связанным с потоками.

Опять-таки, потомки класса Stream представляют данные, как низкоуровневые потоки байт, а непосредственная работа с низкоуровневыми потоками может оказаться довольно загадочной. Некоторые типы, унаследованные от Stream, поддерживают поиск (seeking), что означает возможность получения и изменения текущей позиции в потоке. Чтобы приблизиться к пониманию функциональности класса Stream, рассмотрим список основных его членов, приведенный ниже:

Метод, свойство Описание
CanRead, CanWrite, CanSeek Определяют, поддерживает ли текущий поток чтение, поиск и/или запись
Close() Закрывает текущий поток и освобождает все ресурсы (такие как сокеты и файловые дескрипторы), ассоциированные с текущим потоком. Внутренне этот метод является псевдонимом Dispose(). Поэтому закрытие потока функционально эквивалентно освобождению потока
Flush() Обновляет лежащий в основе источник данных или репозиторий текущим состоянием буфера с последующей очисткой буфера. Если поток не реализует буфер, метод не делает ничего
Length Возвращает длину потока в байтах
Position Определяет текущую позицию в потоке
Read(), ReadByte() Читает последовательность байт (или одиночный байт) из текущего потока и перемещает текущую позицию потока на количество прочитанных байтов
Seek() Устанавливает позицию в текущем потоке
SetLength() Устанавливает длину текущего потока
Write(), WriteByte() Пишет последовательность байт (или одиночный байт) в текущий поток и перемещает текущую позицию на количество записанных байтов

Для чтения и записи в память предусмотрен специальный базовый класс .NET по имени System.IO.MemoryStream, а для работы с сетевыми данными — класс System.Net.Sockets.NetworkStream. Для чтения и записи данных в именованные каналы никаких базовых потоковых классов в .NET не предлагается, но зато имеется один обобщенный потоковый класс System.IO.Stream, от которого можно наследовать нужный класс. Никаких предположений касательно природы внешнего источника данных в классе Stream не делается.

В роли внешнего источника может даже выступать переменная внутри кода. Как бы парадоксально это не звучало, но прием с использованием потоков для передачи данных между переменными может оказываться очень удобным способом для преобразования данных из одного типа в другой. Для преобразования данных из числовых в строковые или для форматирования строк в языке С применялось нечто подобное — функция sprintf.

Преимущество использования отдельного объекта для передачи данных вместо применения для этого классов FileInfo или DirectoryInfo состоит в том, что разделение понятий передачи данных и конкретного источника существенно упрощает изменение этих источников. В самих объектах потоков содержится масса обобщенного кода, касающегося перемещения данных между внешними источниками и переменными в создаваемом самостоятельно коде. Не смешивая этот код с концепцией определенного источника данных, можно значительно повысить возможность его многократного использования в разных обстоятельствах (через наследование).

Например, классы StringReader и StringWriter являются частью одного и того же дерева наследования, как и те два класса, которые будут применяться чуть позже для чтения и записи текстовых файлов. Все классы почти всегда "за кулисами" будут разделять приличную часть кода.

На рисунке показано, как фактически выглядит иерархия классов в пространстве имен System.IO, которые имеют отношение к потокам:

Иерархия классов пространства имен System.IO
Пройди тесты
Лучший чат для C# программистов