Г. Шилдт - Полный справочник по C# (1160789), страница 69
Текст из файла (страница 69)
При возникновении переполнения в checkedблоке генерируется исключение.Управление генерированием исключений с помощью ключевых слов checked илиunchecked может быть полезным в том случае, когда checked/unchecked-статус переполнения определяется использованием соответствующей опции компилятора и настройкой самой среды выполнения.
Таким образом, для некоторых типов программлучше всего явно задавать статус контроля переполнения.374Часть I. Язык С#Полныйсправочник поИспользование средств вводавыводаСсамого начала книги мы использовали часть С#-системы ввода-вывода — методConsole.WriteLine (), но не давали подробных пояснений по этому поводу.Поскольку С#-система ввода-вывода построена на иерархии классов, то ее теорию идетали невозможно освоить, не рассмотрев сначала классы, наследование и исключения.
Теперь настало время для подробного изучения С#-средств ввода-вывода. Поскольку в С# используется система ввода-вывода и классы, определенные средой.NET Framework, в эту тему включено рассмотрение в общих чертах системы вводавывода .NET-среды.В этой главе рассматриваются средства как консольного, так и файлового вводавывода. Необходимо сразу отметить, что С#-система ввода-вывода — довольно обширная тема, и здесь описаны лишь самые важные и часто применяемые средства.Организация С#-системы ввода-выводаСопрограммы выполняют операции ввода-вывода посредством потоков. Поток(stream) — это абстракция, которая либо синтезирует информацию, либо потребляетее. Поток связывается с физическим устройством с помощью С#-системы вводавывода. Характер поведения всех потоков одинаков, несмотря на различные физические устройства, с которыми они связываются.
Следовательно, классы и методы ввода-вывода можно применить ко многим типам устройств. Например, методы, используемые для записи данных на консольное устройство, также можно использовать длязаписи в дисковый файл.Байтовые и символьные потокиНа самом низком уровне все С#-системы ввода-вывода оперируют байтами. И этологично, поскольку многие устройства при выполнении операций ввода-вывода ориентированы на байты. Однако для человека привычнее оперировать символами.Вспомните, что в С# char — это 16-разрядный тип, a byte — 8-разрядный. Если выиспользуете набор символов ASCII, то в преобразовании типов char и byte нет ничего сложного: достаточно проигнорировать старший байт char-значения.
Но такойподход не сработает для остальных Unicode-символов, которым необходимы оба байта. Таким образом, байтовые потоки не вполне подходят для обработки текстового(ориентированного на символы) ввода-вывода. Для решения этой проблемы в С# определен ряд классов, которые преобразуют байтовый поток в символьный, выполняяbyte-char- и char-byte-перевод автоматически.Встроенные потокиТремя встроенными потоками, доступ к которым осуществляется через свойстваConsole. In, Console.Out и Console.Error, могут пользоваться все программы, работающие в пространстве имен System. Свойство Console.Out относится к стандартному выходному потоку. По умолчанию это консоль.
Например, при вызове метода Console.WriteLine (} информация автоматически передается в потокConsole.Out. Свойство Console. In относится к стандартному входному потоку, источником которого по умолчанию является клавиатура. Свойство C o n s o l e . E r r o r относится к ошибкам в стандартном потоке, источником которого также по умолчаниюявляется консоль. Однако эти потоки могут быть перенаправлены на любое совместимое устройство ввода-вывода. Стандартные потоки являются символьными. Следовательно, эти потоки считывают и записывают символы.376Часть I.
Язык С#Классы потоковВ С# определены как байтовые, так и символьные классы потоков. Однако символьные классы потоков в действительности представляют собой оболочки, которыепреобразуют базовый байтовый поток в символьный, причем любое преобразованиевыполняется автоматически. Таким образом, символьные потоки построены на основебайтовых, несмотря на то, что они логически отделены друг от друга.Все классы потоков определены в пространстве имен System.
10. Чтобы иметьвозможность использовать эти классы, в начало программы необходимо включитьследующую инструкцию:1 using System.10;Для ввода и вывода на консоль не нужно задавать пространство имен System. 10,поскольку класс Console определен в пространстве имен System.Класс StreamЦентральную часть потоковой С#-системы занимает класс System. 10.
Stream.Класс stream представляет байтовый поток и является базовым для всех остальныхпотоковых классов. Этот класс также абстрактный, т.е. мы не можем создать его объект. В классе Stream определен набор стандартных потоковых операций. Наиболееприменяемые методы, определенные в классе Stream, перечислены в табл. 14.1.Таблица 14.1. Некоторые методы класса streamМетодv o i d c l o s e ()v o i d F l u s h ()i n t ReadByte ()mtRead (byte [ ] buf,mt offset,m t numBytes)l o n g Seek (long offset,S e e k o n g m origin)v o i d WriteByte (byte Ь)Void w r i t e (byte [ ] buf,int offset,m t numBytes)ОписаниеЗакрывает потокЗаписывает содержимое потока в физическое устройствоВозвращает целочисленное представление следующего доступного байта потока При обнаружении конца файла возвращает значение -1Делает попытку прочитать numBytes байт в массив buf, начиная с элемента buf [offset],возвращает количество успешно прочитанных байтовУстанавливает текущую позицию потока равной указанному значению смещения от заданного начала отсчетаЗаписывает один байт в выходной потокЗаписывает поддиапазон размером numBytes байт из массива buf, начиная с элемента buf[offset]В общем случае при возникновении ошибки ввода-вывода методы, представленные в табл.
14 1, генерируют исключение типа IOException. При попытке выполнитьнекорректную операцию, например, записать данные в поток, предназначенный только для чтения, генерируется исключение типа NotSupportedException.Обратите внимание на то, что в классе stream определены методы, которые считывают и записывают данные. Однако не все потоки поддерживают все эти операции,поскольку возможен вариант, когда поток открывается только для чтения или толькодля записи. Кроме того, не все потоки поддерживают функцию установки в заданнуюпозицию с помощью метода Seek ().
Чтобы определить возможности потока, используйте одно или несколько свойств класса Stream. Они представлены в табл. 14.2. Вэтой таблице также описаны свойства Length и P o s i t i o n , которые содержат длину итекущую позицию потока, соответственно.Глава 14. Использование средств ввода-вывода377Таблица 14.2. Свойства, определенные в классе streamСвойствоОписаниеb o o l canReadСвойство равно значению t r u e , если из потока можно считывать данные. Это свойствопредназначено только для чтенияb o o l canSeekСвойство равно значению t r u e , если поток поддерживает функцию установки в заданнуюпозицию.
Это свойство предназначено только для чтенияb o o l CanwriteСвойство равно значению t r u e , если в поток можно записывать данные. Это свойство предназначено только для чтенияl o n g LengthСвойство содержит длину потока. Это свойство предназначено только для чтенияlong PositionСвойство представляет текущую позицию потока. Это свойство можно как читать, так и устанавливатьБайтовые классы потоковИз класса s t r e a m выведены такие байтовые классы потоков.Класс потокаОписаниеBuf f eredstreamЗаключает в оболочку байтовый поток и добавляет буферизацию. Буферизация во многихслучаях увеличивает производительностьFilestreamБайтовый поток, разработанный для файлового ввода-выводаMemorystreamБайтовый поток, который использует память для хранения данныхПрограммист может также вывести собственные потоковые классы.
Однако дляподавляющего большинства приложений достаточно встроенных потоков.Символьные классы потоковЧтобы создать символьный поток, поместите байтовый поток в одну из символьных потоковых С#-оболочек. В вершине иерархии символьных потоков находятся абстрактные классы TextReader и TextWriter. Класс TextReader предназначен дляобработки операций ввода данных, а класс TextWriter — для обработки операцийвывода данных. Методы, определенные этими двумя абстрактными классами, доступны для всех их подклассов. Следовательно, они образуют минимальный набор функций ввода-вывода, который будут иметь все символьные потоки.В табл. 14.3 перечислены методы ввода данных, принадлежащие классу TextReader.В случае ошибки эти методы могут генерировать исключение типа lOException.(Некоторые методы могут также генерировать и другие типы исключений.) Особоговнимания заслуживает метод ReadLine (), который считывает целую строку текста,возвращая ее в качестве string-значения.
Этот метод полезен при считывании входных данных, которые содержат пробелы.Таблица 14.3. Методы ввода данных, определенные в классе TextReaderМетодv o i d c l o s e ()intPeek оintRead о378Описание*Закрывает источник ввода данныхПолучает следующий символ из входного потока, но не удаляет его. Возвращает значение - 1 , если ни один символ не доступен- Возвращает целочисленное представление следующего доступного символа из вызывающего объекта входного потока.
При обнаружении концафайла возвращает значение -1Часть I. Язык С#Окончание табл. 14.3МетодОписаниеint Read (char [] buf,int offset,int numChars)Делает попытку прочитать numChars символов в массив buf, начинаяс элемента b u f [ o f f s e t ] , и возвращает количество успешно прочитанных символовint ReadBlock(char[] buf,Делает попытку прочитать numChars символов в массив buf, начинаяint offset,с элемента buf[ offset],и возвращает количество успешно прочиint numChars) танных символовstring ReadLineOСчитывает следующую строку текста и возвращает ее как s t r i n g значение.
При попытке прочитать признак конца файла возвращаетnull-значениеstring ReadToEndOСчитывает все символы, оставшиеся в потоке, и возвращает их какstring-значениеВ классе TextWriter определены версии методов Write () и W r i t e L i n e O , которые могут выводить данные всех встроенных типов.