Тема 13. Потоки данных

Класс Stream

Класс Stream предоставляет универсальное представление последовательности байтов ( поток байтов ).

Потоки включают три основные операции:

  • Чтение из потока — это перенос информации из потока в структуру данных, такую как массив байтов;
  • Запись в поток — это передача данных из структуры данных в поток;
  • Поиск. Потоки поддерживают поиск. Чтение — это перенос данных из потока в такую структуру данных, как массив байтов. Возможность поиска зависит от вида резервного хранилища потока. Например, в сетевых потоках отсутствует унифицированное представление текущего положения, поэтому обычно они не поддерживают поиск.

Класс Stream является абстрактным базовым классом всех потоков. Поток — это абстракция последовательности байтов, например файл, устройство ввода-вывода, канал взаимодействия процессов или сокет TCP/IP. Класс Stream и его производные классы обеспечивают универсальное представление этих различных типов ввода и вывода и программист изолировано от конкретных сведений операционной системы и основных устройств.

В зависимости от лежащих в основе источника или хранилища данных потоки могут поддерживать только некоторые из этих возможностей. Можно запросить поток для ее возможности с помощью CanRead, CanWrite и свойства CanSeek класса Stream.

Методы Read и Write позволяют выполнять чтение и запись данных в различных форматах. Если поток поддерживает поиск, для отправки запросов и изменения текущего положения и длины потока рекомендуется использовать методы Seek, SetLength, а также свойства Position, Length.

Класс FileStream

Класс FileStream используется для чтения и записи файлов. Мы можем использовать этот класс для чтения и записи байтов, символов, строк и других типов данных. Класс FileStream поддерживает синхронное и асинхронное открытие файлов, синхронные операции чтения и записи (методы Read и Write), а также асинхронные операции чтения и записи (методы BeginRead и BeginWrite). Асинхронные операции завершаются вызовом методов EndRead и EndWrite соответственно. Режим по умолчанию — синхронный; для проверки режима мы используем свойство IsAsync. Для асинхронных операций необходим объект WaitHandle. Метод Seek используется для произвольного доступа к файлам. Свойство Position позволяет нам узнать или установить текущую позицию в потоке. Методы Lock и Unlock служат для предотвращения доступа ко всему файлу или к его части, а также для отмены ранее установленного запрета доступа. Свойство Length возвращает длину потока в байтах, а метод SetLength служит для задания длины потока. Методы ReadByte и WriteByte используются для чтения и записи одного байта. Для других примитивных типов нам необходимы классы BinaryReader и BinaryWriter соответственно.

От класса FileStream наследует класс IsolatedStorageFileSystem (пространство имен System.IO.IsolatedStorage), служащий для чтения, записи и создания файлов в изолированном хранилище. Изолированное хранилище предоставляет в наше распоряжение виртуальную файловую систему, позволяющую читать и записывать данные, недоступные извне. Изолированное хранилище обеспечивает изоляцию данных на уровне пользователя, сборки или домена приложения.

Чтение из файла

Для чтения данных из потока можно использовать класс StreamReader. В нем реализовано множество методов для удобного считывания данных. Ниже приведена программа, которая выводит содержимое файла на экран:

static void Main(string[] args)
{
   //создаем файловый поток
   FileStream file1 =
      new FileStream("d:\\test.txt", FileMode.Open);

    // создаем «потоковый читатель» и
   //  связываем его с файловым потоком
   StreamReader reader =
      new StreamReader(file1);

   //считываем все данные с потока и выводим на экран
   Console.WriteLine(reader.ReadToEnd());

   //закрываем поток
   reader.Close();

   Console.ReadLine();
}

Метод ReadToEnd() считывает все данные из файла. ReadLine() – считывает одну строку (указатель потока при этом переходит на новую строку, и при следующем вызове метода будет считана следующая строка).

Запись в файл

Для записи данных в поток используется класс StreamWriter. Пример записи в файл:

static void Main(string[] args)
{
   // создаем файловый поток
   FileStream file1 =
       new FileStream("d:\\test.txt", FileMode.Create);

   // создаем «потоковый писатель» и
   // связываем его с файловым потоком
   StreamWriter writer =
       new StreamWriter(file1);

   //записываем в файл
   writer.Write("текст");

   // закрываем поток.
   // если поток не закрыт, возможны ошибки в файле
   writer.Close();
}

Метод WriteLine() записывает в файл построчно (то же самое, что и простая запись с помощью Write(), только в конце добавляется новая строка).

Нужно всегда помнить, что после работы с потоком, его нужно закрыть (освободить ресурсы), использовав метод Close().

Класс MemoryStream

Класс MemoryStream может использоваться для создания потока, содержимое которого хранится не на диске и не в сети, а в памяти. Этот класс задействует байтовый массив, который может иметь либо фиксированную, либо произвольную длину. В последнем случае мы можем изменять размер массива, читать из него и записывать в него. Что касается потока с фиксированной длиной, то в него мы можем только записывать.

Для того чтобы выяснить число байтов, выделенных под поток в памяти, мы пользуемся свойством Capacity, возвращающим данные типа Integer. Свойство Length возвращает реальное число байтов в потоке (значение типа Long), а метод GetBuffer() возвращает массив байтов, в котором располагается поток. Для сохранения всего содержимого потока в байтовом массиве используется метод ToArray(). Метод WriteTo(Stream) служит для копирования всего потока в другой поток.

Класс NetworkStream

Этот класс служит для посылки данных по сети. Класс NetworkStream реализует поток, не поддерживающий операцию позиционирования. Поэтому мы не можем использовать свойство Position и метод Seek при работе с потоком этого типа.

Текстовые потоки

Базовые потоки обеспечивают ввод/вывод байтов, т.е. двоичной информации. Однако часто требуется обеспечить ввод/вывод текстовой информации. Для реализации ввода/вывода текста необходимо перекодировать потоки бийтов в символы и наоборот. Подобная функциональность достигается применением следующих классов-настроек TextReader, TextWriter, StreamReader, StreamWriter, StringReader, StringWriter.

Дополнительная литература

http://metanit.com/sharp/tutorial/5.4.php
http://metanit.com/sharp/tutorial/5.5.php
http://metanit.com/sharp/tutorial/5.6.php
http://www.mista.ru/net/stream.htm

results matching ""

    No results matching ""