Добавить в цитаты Настройки чтения

Страница 216 из 502

<b>      // Читать из объекта memstrm средствами</b>

<b>      // ввода данных из потока,</b>

<b>      memstrm.Seek(0, SeekOrigin.Begin); // -установить указатель файла</b>

<b>                          // в исходное положение</b>

<b>      string str = memrdr.ReadLine();</b>

<b>      while(str != null) {</b>

<b>        str = memrdr.ReadLine();</b>

<b>        if(str[0] == '.') break;</b>

<b>        Console.WriteLine(str);</b>

<b>      }</b>

<b>    } catch(IOException exc) {</b>

<b>      Console.WriteLine(&quot;Ошибка ввода-вывода&quot; + exc.Message);</b>

<b>    } finally {</b>

<b>      // Освободить ресурсы считывающего и записывающего потоков,</b>

<b>      memwtr.Close();</b>

<b>      memrdr.Close() ;</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Вот к какому результату приводит выполнение этой программы.

<b>Чтение прямо из массива storage:</b>

<b>byte [0]: 0</b>

<b>byte [1]: 1</b>

<b>byte [2]: 2</b>

<b>byte [3]: 3</b>

<b>byte [4]: 4</b>

<b>byte [5]: 5</b>

<b>byte [6]: 6</b>

<b>byte [7]: 7</b>

<b>byte [8]: 8</b>

<b>byte [9]: 9</b>

<b>Чтение из потока с помощью объекта memrdr:</b>

<b>byte [1]: 1</b>

<b>byte [2]: 2</b>

<b>byte [3]: 3</b>

<b>byte [4]: 4</b>

<b>byte [5]: 5</b>

<b>byte [6]: 6</b>

<b>byte [7]: 7</b>

<b>byte [8]: 8</b>

<b>byte [9]: 9</b>

В этой программе сначала создается массив байтов, называемый storage. Затем этот массив используется в качестве основной памяти для объекта memstrm класса MemoryStream. Из объекта memstrm, в свою очередь, создаются объекты memrdr класса StreamReader и memwtr класса StreamWriter. С помощью объекта memwtr выводимые данные записываются в запоминающий поток. Обратите внимание на то, что после записи выводимых данных для объекта memwtr вызывается метод Flush(). Это необходимо для того, чтобы содержимое буфера этого объекта записывалось непосредственно в базовый массив. Далее содержимое базового массива байтов отображается вручную в цикле for each. После этого указатель файла устанавливается с помощью метода Seek() в начало запоминающего потока, из которого затем вводятся данные с помощью объекта потока memrdr.

Запоминающие потоки очень полезны для программирования. С их помощью можно, например, организовать сложный вывод с предварительным накоплением данных в массиве до тех пор, пока они не понадобятся. Этот прием особенно полезен для программирования в такой среде с графическим пользовательским интерфейсом, как Windows. Кроме того, стандартный поток может быть переадресован из массива. Это может пригодиться, например, для подачи тестовой информации в программу.

Применение классов StringReader и StringWriter

Для выполнения операций ввода-вывода с запоминанием в некоторых приложениях в качестве базовой памяти иногда лучше использовать массив типа string, чем массив типа byte. Именно для таких случаев и предусмотрены классы StringReader и StringWriter. В частности, класс StringReader наследует от класса TextReader, а класс StringWriter — от класса TextWriter. Следовательно, они представляют собой потоки, имеющие доступ к методам, определенным в этих двух базовых классах, что позволяет, например, вызывать метод ReadLine() для объекта класса StringReader, а метод WriteLine() — для объекта класса StringWriter.

Ниже приведен конструктор класса StringReader:

<b>StringReader(string s)</b>

где s обозначает символьную строку, из которой производится чтение.

В классе StringWriter определено несколько конструкторов. Ниже представлен один из наиболее часто используемых.

<b>StringWriter()</b>

Этот конструктор создает записывающий поток, который помещает выводимые данные в строку. Для получения содержимого этой строки достаточно вызвать метод ToString().

Ниже приведен пример, демонстрирующий применение классов StringReader и StringWriter.

<b>// Продемонстрировать применение классов StringReader и StringWriter.</b>

<b>using System; using</b>