Страница 215 из 502
<b> ch = (char) f.ReadByte() ;</b>
<b> Console.WriteLine("Пятая буква: " + ch) ;</b>
<b> Console.WriteLine() ;</b>
<b> //А теперь прочитать буквы английского алфавита через одну.</b>
<b> Console.WriteLine("Буквы алфавита через одну: ");</b>
<b> for(int i=0; i < 26; i += 2) {</b>
<b> f.Seek(i, SeekOrigin.Begin); // найти i-й символ </b>
<b> ch = (char) f.ReadByte() ;</b>
<b> Console.Write(ch + " ") ;</b>
<b> }</b>
<b> }</b>
<b> catch(IOException exc) {</b>
<b> Console.WriteLine("Ошибка ввода-вывода" + exc.Message);</b>
<b> } finally {</b>
<b> if(f != null) f.Close();</b>
<b> }</b>
<b> Console.WriteLine() ;</b>
<b> }</b>
<b>}</b>
При выполнении этой программы получается следующий результат.
<b>Первая буква: А </b>
<b>Вторая буква: В </b>
<b>Пятая буква: Е</b>
<b>Буквы алфавита, через одну:</b>
<b>А С Е G I K M O Q S U W Y</b>
Несмотря на то что метод Seek() имеет немало преимуществ при использовании с файлами, существует и другой способ установки текущего положения в файле с помощью свойства Position. Как следует из табл. 14.2, свойство Position доступно как для чтения, так и для записи. Поэтому с его помощью можно получить или же установить текущее положение в файле. В качестве примера ниже приведен фрагмент кода из предыдущей программы записи и чтения из файла с произвольным доступом random.dat, измененный с целью продемонстрировать применение свойства Position.
<b>Console.WriteLine("Буквы алфавита через одну: ");</b>
<b>for(int i=0; i < 26; i += 2) {</b>
<b> f.Position = i; // найти i-й символ посредством свойства Position </b>
<b> ch = (char) f.ReadByte();</b>
<b> Console.Write(ch + " ");</b>
<b>}</b>
Применение класса MemoryStream
Иногда оказывается полезно читать вводимые данные из массива или записывать выводимые данные в массив, а не вводить их непосредственно из устройства или выводить прямо на него. Для этой цели служит класс MemoryStream. Он представляет собой реализацию класса Stream, в которой массив байтов используется для ввода и вывода. В классе MemoryStream определено несколько конструкторов. Ниже представлен один из них:
<b>MemoryStream(byte[] buffer)</b>
где buffer обозначает массив байтов, используемый в качестве источника или адресата в запросах ввода-вывода. Используя этот конструктор, следует иметь в виду, что массив buffer должен быть достаточно большим для хранения направляемых в него данных.
В качестве примера ниже приведена программа, демонстрирующая применение класса MemoryStream в операциях ввода-вывода.
<b>// Продемонстрировать применение класса MemoryStream.</b>
<b>using System;</b>
<b>using System.IO;</b>
<b>class MemStrDemo {</b>
<b> static void Main() {</b>
<b> byte[] storage = new byte[255];</b>
<b> // Создать запоминающий поток.</b>
<b> MemoryStream memstrm = new MemoryStream(storage);</b>
<b> // чтения и записи данных в потоки.</b>
<b> StreamWriter memwtr = new StreamWriter(memstrm);</b>
<b> StreamReader memrdr = new StreamReader(memstrm);</b>
<b> try {</b>
<b> // Записать данные в память, используя объект memwtr.</b>
<b> for(int i=0; i < 10; i++)</b>
<b> memwtr.WriteLine("byte [" + i + "]: " + i);</b>
<b> // Поставить в конце точку, </b>
<b> memwtr.WriteLine(".");</b>
<b> memwtr.Flush() ;</b>
<b> Console.WriteLine("Чтение прямо из массива storage: ");</b>
<b> // Отобразить содержимое массива storage непосредственно.</b>
<b> foreach(char ch in storage) {</b>
<b> if (ch == '.') break;</b>
<b> Console.Write(ch);</b>
<b> }</b>
<b> Console.WriteLine("nЧтение из потока с помощью объекта memrdr: ");</b>