Г. Шилдт - Полный справочник по C# (1160789), страница 75
Текст из файла (страница 75)
Язык С#memwtr'.WriteLine("byte[" + i + "] : " + i) ;// Ставим в конце точку,merawtr.Write (f . ') ;memwtr.Flush();Console.WriteLine("Считываем данные прямо из массива storage:// Отображаем напрямую содержимое памяти.foreach(char ch in storage) {if (ch == '.') break;Console.Write(ch);Console.WriteLine("ХпСчитываем данные посредством объекта memrdr: " ) ;// Считываем данные из объекта memstrm, используя// средство чтения потоков.menistrm.Seek(O, SeekOrigin.Begin) ; // Установка// указателя позиции в начало потока.string str = memrdr.ReadLine();while(str != null) {str = memrdr.ReadLine();if (str.CompareToC1.11) == 0) break;Console.WriteLine(str) ;Вот как выглядят результаты выполнения этой программы:Считываем данные прямо из массива storage:byte [0]: 0byte [1]: 1byte [2]: 2byte [3]: 3byte [4]: 4byte [5]: 5byte [6]: 6byte [7]: 7byte [8]: 8byte [9]: 9Считываем данные посредством объекта memrdr:byte [1]: 1byte [2] : 2byte [3]: 3byte [4]: 4byte [5]: 5byte [6]: 6byte [7]: 7byte [8]: 8byte [9]: 9Глава 14.
Использование средств ввода-вывода403В этой программе создается байтовый массив storage. Этот массив затем используется в качестве базовой области памяти для объекта memstrcn класса Memory Stream.На основе объекта memstrm создаются объект класса StreamReader с именем memrdrи объект класса StreamWritex с именем memwtr. Через объект memwtr данные записываются в поток, ориентированный на конкретную область памяти. Обратите внимание на то, что после записи выходных данных для объекта memwtr вызывается метод flush (). Тем самым гарантируется, что содержимое буфера, связанного с потоком memwtr, реально перепишется в базовый массив.
Затем содержимое этогобайтового массива отображается "вручную", т.е. с помощью цикла foreach. Послеэтого посредством метода Seek () указатель позиции устанавливается в начало потока,и его содержимое считывается с использованием объекта memrdr.Потоки, ориентированные на память, весьма полезны в программировании. Например, можно заблаговременно составить выходные данные и хранить их в массиведо тех пор, пока в них не отпадет необходимость.
Такой подход особенно полезен впрограммировании для такой GUI-среды, как Windows. Можно также перенаправитьстандартный поток для считывания данных из массива. Это полезно, например, привводе тестовой информации в программу.Использование классов StringReader ИStringWriterВ некоторых приложениях при выполнении операций ввода-вывода, ориентированных на использование памяти в качестве базовой области хранения данных, прощеработать не с байтовыми (byte-) массивами, а со строковыми (string-). В этом случае используйте классы StringReader и StringWriter. Класс StringReader наследует класс TextReader, а класс StringWriter — класс TextWriter.
Следовательно,эти потоки имеют доступ к методам, определенным в этих классах. Например, выможете вызывать метод ReadLineO для объекта класса StringReader и методWriteLine () для объекта класса StringWriter.Конструктор класса StringReader имеет следующий вид:S t r i n g R e a d e r ( s t r i n g str)Здесь параметр s t r представляет собой строку, из которой должны считыватьсяданные.В классе StringWriter определено несколько конструкторов.
Мы будем использовать такой:StringWriter()Этот конструктор создает "записывающий" механизм, который помещает выходные данные в строку. Эта строка автоматически создается объектом классаStringWriter. Содержимое строки можно получить, вызвав метод T o S t r i n g O .Рассмотрим пример использования классов StringReader и StringWriter.// Демонстрация использования классов StringReader// и StringWriter.using System;using System.10;class StrRdrDemo {public static void Main() {// Создаем объект класса StringWriter.404Часть I.
Язык С#StringWriter strwtr = new StringWriter();// Записываем данные в StringWriter-объект.for(int i=0; i < 10; i++)strwtr.WriteLine("Значение i равно: " + i ) ;// Создаем объект класса StringReader.StringReader strrdr = new StringReader(strwtr.ToStringO ) ;// Теперь считываем данные из StringReader-объекта.string str = strrdr.ReadLine();while(str != null) {str = strrdr.ReadLine();Console.WriteLine(str) ;Результаты выполнения этой программы имеют такой вид:Значение i равно: 1Значение i равно: 2Значение i равно: 3Значение i равно: 4Значение i равно: 5Значение i равно: бЗначение i равно: 7Значение i равно: 8Значение i равно: 9Эта программа сначала создает объект класса S t r i n g W r i t e r с именем s t r w t r изаписывает в него данные с помощью метода WriteLine (). Затем создается объекткласса StringReader с использованием строки, содержащейся в объекте s t r w t r , иметода T o S t r i n g O .
Наконец, содержимое строки считывается с помощью методаReadLine ().Преобразование числовых строк во внутреннеепредставлениеПрежде чем завершить тему ввода-вывода, рассмотрим метод, который будет весьма полезен программистам при считывании числовых строк. Как вы знаете, С#-методWriteLine () предоставляет удобный способ вывода данных различных типов(включая числовые значения таких встроенных типов, как i n t и double) на консольное устройство. Следовательно, метод WriteLine () автоматически преобразует числовые значения в удобную для восприятия человеком форму. Однако С# не обеспечивает обратную функцию, т.е. метод ввода, который бы считывал и преобразовывалстроковые представления числовых значений во внутренний двоичный формат.
Например, не существует метода ввода данных, который бы считывал такую строку, как"100", и автоматически преобразовывал ее в соответствующее двоичное значение, которое можно было бы хранить в int-переменной. Для решения этой задачи понадобится метод, определенный для всех встроенных числовых типов, — Parse ().Глава 14. Использование средств ввода-вывода405Приступая к решению этой задачи, необходимо отметить такой важный факт. Всевстроенные С#-типы (например, i n t и double) в действительности являются лишьпсевдонимами (т.е. другими именами) для структур, определенных в среде .NETFramework.
Компания Microsoft заявляет, что понятия С#-типа и .NET-типа структурынеразличимы. Первое — просто еще одно имя для другого. Поскольку С#-типы значений поддерживаются структурами, они имеют члены, определенные для этих структур.Ниже представлены .NET-имена структур и их С#-эквиваленты (в виде ключевыхслов) для числовых типов..NET'имя структурыСП-имяDecimaldecimalDoubledoubleSinglefloatIntl6shortInt32intInt64longUIntl6ushortUInt32uintUInt64ulongBytebyteSbytesbyteЭти структуры определены в пространстве имен System. Таким образом, составноеимя для структуры Int32 "звучит" как System.
I n t 3 2 . Для этих структур определенширокий диапазон методов, которые способствуют полной интеграции типов значений в С#-иерархию объектов. В качестве дополнительного "вознаграждения" эти числовые структуры также определяют статические методы, которые преобразуют числовую строку в соответствующий двоичный эквивалент. Эти методы преобразованияпредставлены в следующей таблице. Каждый метод возвращает двоичное значение,которое соответствует строке.СтруктураМетод преобразованияDecimalstatic decimal Parse(string str)Doublestatic double Parse(string str)Singlestatic float Parse(string str)Int64static long Parse(string str)Int32static int Parse(string str)Intl6static short Parse(string str)UInt64static ulong Parse(string str)UInt32static uint Parse(string str)UIntl6static ushort Parse(string str)Bytestatic byte Parse(string str)SBytestatic sbyte Parse(string str)Методы Parse () генерируют исключение типа FormatException, если параметрstr не содержит числа, допустимого для типа вызывающего объекта.
Если параметрstr имеет null-значение, генерируется исключение типа ArgumentNullException, a406Часть I. Язык С#если значение параметра str превышает диапазон, допустимый для типа вызывающего объекта, — исключение типа Overf lowException.Методы синтаксического анализа позволяют легко преобразовать числовое значение, прочитанное в виде строки с клавиатуры или текстового файла, в соответствующий внутренний формат. Например, следующая программа вычисляет среднее арифметическое от чисел, введенных пользователем в виде списка.
Сначала пользователюпредлагается ввести количество усредняемых чисел, а затем программа считывает этичисла с помощью метода ReadLineO и с помощью метода I n t 3 2 . Parse () преобразует строки в целочисленное значение. Затем она вводит значения, используя методDouble. Parse () для преобразования строк в их double-эквиваленты.// Эта программа усредняет список чисел,// введенных пользователем.usingusingSystem;System.10;c l a s s AvgNums {p u b l i c s t a t i c void Main() {string str;i n t n;double sum = 0 . 0 ;double avg, t ;/Console.Write("Сколько чисел вы собираетесь ввести: " ) ;s t r = Console.ReadLine();try {n = Int32.Parse(str) ;}catch(FormatException exc) {Console.WriteLine(exc.Message);n = 0;}catch(OverflowException exc) {Console.WriteLine(exc.Message);n = 0;ч}Console.WriteLine("Введите " + n + " чисел.");for(int i=0; i < n ; i++) {Console.Write(": ") ;str = Console.ReadLine();try {t = Double.Parse(str);} catch(FormatException exc) {Console.WriteLine(exc.Message);t - 0.0;}catch(OverflowException exc) {Console.WriteLine(exc.Message);t = 0;}sum += t;}avg = sum / n;Console.WriteLine("Среднее равно " + avg);Глава 14.
Использование средств ввода-вывода,407Вот как могут выглядеть результаты выполнения этой программы:Сколько чисел вы собираетесь ввести: 5Введите 5 чисел.: 1.1: 2.2: 3.3: 4.4: 5.5Среднее равно 3.3И еще. Вы должны использовать надлежащий метод анализа для типа значения,которое вы пытаетесь преобразовать. Например, попытка использовать методI n t 3 2 . Parse () для строки, содержащей значение с плавающей точкой, желаемогорезультата не даст.408Часть I. Язык С#Полныйсправочник поДелегаты исобытияВэтой главе рассматриваются два новых С#-средства: делегаты и события. Делегат предоставляет возможность инкапсулировать метод, а событие — это своегорода уведомление о том, что имело место некоторое действие.
Делегаты и событиясвязанны между собой, поскольку событие создается на основе делегата. Эти средстварасширяют диапазон задач программирования, к которым можно применить язык С#.ДелегатыНачнем с определения термина делегат (delegate). Делегат — это объект, которыйможет ссылаться на метод.