Страница 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("Ошибка ввода-вывода" + 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>