В качестве примера ниже приведена программа, демонстрирующая применение класса MemoryStream в операциях ввода-вывода. // Продемонстрировать применение класса MemoryStream. using System; using System.IO; class MemStrDemo { static void Main { byte[] storage = new byte[255]; // Создать запоминающий поток. MemoryStream memstrm = new MemoryStream(storage); // Заключить объект memstrm в оболочки классов // чтения и записи данных в потоки. StreamWriter memwtr = new StreamWriter(memstrm); StreamReader memrdr = new StreamReader(memstrm); try { // Записать данные в память, используя объект memwtr. for(int i=0; i < 10; i++) memwtr.WriteLine("byte [" + i + "]: " + i); // Поставить в конце точку. memwtr.WriteLine("."); memwtr.Flush; Console.WriteLine("Чтение прямо из массива storage: "); // Отобразить содержимое массива storage непосредственно, foreach(char ch in storage) { if (ch == '.') break; Console.Write(ch); } Console.WriteLine("\nЧтение из потока с помощью объекта memrdr: "); // Читать из объекта memstrm средствами ввода данных из потока. memstrm.Seek(0, SeekOrigin.Begin); // установить указатель файла // в исходное положение string str = memrdr.ReadLine; while(str != null) { str = memrdr .ReadLine; if (str[0] == '.') break; Console.WriteLine(str); } } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода\n" + exc.Message); } finally { // Освободить ресурсы считывающего и записывающего потоков. memwtr.Close; memrdr.Close; } } }
Вот к какому результату приводит выполнение этой программы. Чтение прямо из массива storage: byte [0]: 0 byte [1]: 1 byte [2]: 2 byte [3]: 3 byte [4]: 4 byte [5]: 5 byte [6]: 6 byte [7]: 7 byte [8]: 8 byte [9]: 9 Чтение из потока с помощью объекта memrdr: byte [1]: 1 byte [2]: 2 byte [3]: 3 byte [4]: 4 byte [5]: 5 byte [6]: 6 byte [7]: 7 byte [8]: 8 byte [9]: 9
В этой программе сначала создается массив байтов, называемый storage. Затем этот массив используется в качестве основной памяти для объекта memstrm класса MemoryStream. Из объекта memstrm, в свою очередь, создаются объекты memrdr клас са StreamReader и memwtr класса StreamWriter. С помощью объекта memwtr выво димые данные записываются в запоминающий поток. Обратите внимание на то, что после записи выводимых данных для объекта memwtr вызывается метод Flush. Это необходимо для того, чтобы содержимое буфера этого объекта записывалось непо средственно в базовый массив. Далее содержимое базового массива байтов отобража ется вручную в цикле foreach. После этого указатель файла устанавливается с по мощью метода Seek в начало запоминающего потока, из которого затем вводятся данные с помощью объекта потока memrdr.
Запоминающие потоки очень полезны для программирования. С их помощью можно, например, организовать сложный вывод с предварительным накоплением данных в массиве до тех пор, пока они не понадобятся. Этот прием особенно поле зен для программирования в такой среде с графическим пользовательским интер фейсом, как Windows. Кроме того, стандартный поток может быть переадресован из массива. Это может пригодиться, например, для подачи тестовой информации в программу. Применение классов StringReader и StringWriter
Для выполнения операций ввода-вывода с запоминанием в некоторых приложе ниях в качестве базовой памяти иногда лучше использовать массив типа string, чем массив типа byte. Именно для таких случаев и предусмотрены классы StringReader и StringWriter. В частности, класс StringReader наследует от класса TextReader, а класс StringWriter — от класса TextWriter. Следовательно, они представля ют собой потоки, имеющие доступ к методам, определенным в этих двух базовых классах, что позволяет, например, вызывать метод ReadLine для объекта класса StringReader, а метод WriteLine — для объекта класса StringWriter.
Ниже приведен конструктор класса StringReader: StringReader(string s)
где s обозначает символьную строку, из которой производится чтение.
В классе StringWriter определено несколько конструкторов. Ниже представлен один из наиболее часто используемых. StringWriter
Этот конструктор создает записывающий поток, который помещает выводимые данные в строку. Для получения содержимого этой строки достаточно вызвать метод ToString.