Console.Write(ch + " ");
}
Применение класса MemoryStream
Иногда оказывается полезно читать вводимые данные из массива или записывать выводимые данные в массив, а не вводить их непосредственно из устройства или выводить прямо на него. Для этой цели служит класс MemoryStream. Он представляет собой реализацию класса Stream, в которой массив байтов используется для ввода и вывода. В классе MemoryStream определено несколько конструкторов. Ниже представлен один из них:
MemoryStream(byte[ ] buffer)
где buffer обозначает массив байтов, используемый в качестве источника или адресата в запросах ввода-вывода. Используя этот конструктор, следует иметь в виду, что массив buffer должен быть достаточно большим для хранения направляемых в него данных.
В качестве примера ниже приведена программа, демонстрирующая применение класса MemoryStream в операциях ввода-вывода.
// Продемонстрировать применение класса MemoryStream.
using System; using System.10;
class MemStrDemo { static void Main() {
byte[] storage = new byte[255];
// Создать запоминающий поток.
MemoryStream memsttm = new MemoryStream(storage);
// чтения и записи данных в потоки.
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("ХпЧтение из потока с помощью объекта 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("Ошибка ввода-вывода\п" + 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 () . Это необходимо для того, чтобы содержимое буфера этого объекта записывалось непосредственно в базовый массив. Далее содержимое базового массива байтов отображается вручную в цикле for each. После этого указатель файла устанавливается с помощью метода Seek () в начало запоминающего потока, из которого затем вводятся данные с помощью объекта потока memrdr.
Запоминающие потоки очень полезны для программирования. С их помощью можно, например, организовать сложный вывод с предварительным накоплением данных в массиве до тех пор, пока они не понадобятся. Этот прием особенно полезен для программирования в такой среде с графическим пользовательским интерфейсом, как Windows. Кроме того, стандартный поток может быть переадресован из массива. Это может пригодиться, например, для подачи тестовой информации в программу.
Читать дальше