Полное руководство. С# 4.0 - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
Некоторые из методов, перечисленных в табл. 14.1, генерируют исключениеIOException при появлении ошибки ввода-вывода. Если же предпринимается попытка выполнить неверную операцию, например вывести данные в поток, предназначенный только для чтения, то генерируется исключение NotSupportedException.Кроме того, могут быть сгенерированы и другие исключения — все зависит от конкретного метода.
Следует заметить, что в классе Stream определены методы для ввода (или чтения)и вывода (или записи) данных. Но не все потоки поддерживают обе эти операции,поскольку поток можно открывать только для чтения или только для записи. Крометого, не все потоки поддерживают запрос текущего положения в потоке с помощьюметода Seek(). Для того чтобы определить возможности потока, придется воспользоваться одним, а то и несколькими свойствами класса Stream. Эти свойства перечислены в табл. 14.2 наряду со свойствами Length и Position, содержащими длину потокаи текущее положение в нем.
Таблица 14.2. Свойства, определенные в классе StreamСвойствоОписаниеbool CanReadПринимает значение true, если из потока можно ввести данные. Доступно только для чтенияbool CanSeekПринимает значение true, если поток поддерживает запрос текущего положения в потоке. Доступно только для чтенияbool CanWriteПринимает значение true, если в поток можно вывести данные. Доступно только для чтенияlong LengthСодержит длину потока. Доступно только для чтенияlong PositionПредставляет текущее положение в потоке. Доступно как для чтения, так и для записиint ReadTimeoutПредставляет продолжительность времени ожидания в операциях ввода. Доступно как для чтения, так и для записиint WriteTimeoutПредставляет продолжительность времени ожидания в операциях вывода. Доступно как для чтения, так и для записиКлассы байтовых потоков
Производными от класса Stream являются несколько конкретных классов байтовыхпотоков. Эти классы определены в пространстве имен System.IO и перечислены ниже.Класс потокаОписаниеBufferedStreamЗаключает в оболочку байтовый поток и добавляет буферизацию. Буферизация, как правило, повышает производительностьFileStreamБайтовый поток, предназначенный для файлового ввода-выводаMemoryStreamБайтовый поток, использующий память для хранения данныхUnmanagedMemoryStreamБайтовый поток, использующий неуправляемую память для хранения данных
В среде NET Framework поддерживается также ряд других конкретных классов потоков, в том числе для ввода-вывода в сжатые файлы, сокеты и каналы. Кроме того,можно создать свои собственные производные классы потоков, хотя для подавляющегочисла приложений достаточно и встроенных потоков.Классы-оболочки символьных потоков
Для создания символьного потока достаточно заключить байтовый поток в одиниз классов-оболочек символьных потоков. На вершине иерархии классов символьных потоков находятся абстрактные классы TextReader и TextWriter. Так, классTextReader организует ввод, а класс TextWriter — вывод. Методы, определенныев обоих этих классах, доступны для всех их подклассов. Они образуют минимальныйнабор функций ввода-вывода, которыми должны обладать все символьные потоки.
В табл. 14.3 перечислены методы ввода, определенные в классе TextReader. В целом, эти методы способны генерировать исключение IOException при появленииошибки ввода, а некоторые из них — исключения других типов. Особый интерес вызывает метод ReadLine(), предназначенный для ввода целой текстовой строки, возвращая ее в виде объекта типа string. Этот метод удобен для чтения входных данных,содержащих пробелы. В классе TextReader имеется также метод Close(), определяемый следующим образом.void Close()
Этот метод закрывает считывающий поток и освобождает его ресурсы.
Таблица 14.3. Методы ввода, определенные в классе TextReaderМетодОписаниеint Рeек()Получает следующий символ из потока ввода, но не удаляет его. Возвращает значение -1, если ни один из символов не доступенint Read()Возвращает целочисленное представление следующего доступного символа из вызывающего потока ввода. При обнаружении конца потока возвращает значение -1int Read(char[]buffer, int index, int count)Делает попытку ввести количество count символов в массив buffer, начиная с элемента buffer[index], и возвращает количество успешно введенных символовint ReadBlock(char[]buffer, int index, int count)Делает попытку ввести количество count сим волов в массив buffer, начиная с элемента buffer[index], и возвращает количество успешно введенных символовstring ReadLine()Вводит следующую текстовую строку и возвращает ее в виде объекта типа string. При попытке прочитать признак конца файла возвращает пустое значениеstring ReadToEnd()Вводит все символы, оставшиеся в потоке, и возвращает их в виде объекта типа string
В классе TextWriter определены также варианты методов Write() и WriteLine(),предназначенные для вывода данных всех встроенных типов. Ниже в качестве примера перечислены лишь некоторые из перегружаемых вариантов этих методов.МетодОписаниеvoid Write(int value)Выводит значение типа intvoid Write(double value)Выводит значение типа doublevoid Write(bool value)Выводит значение типа boolvoid WriteLine(string value)Выводит значение типа string с последующим символом новой строкиvoid WriteLine(uint value)Выводит значение типа uint с последующим символом новой строкиvoid WriteLine(char value)Выводит символ с последующим символом новой строки
Все эти методы генерируют исключение IOException при появлении ошибкивывода.
Кроме того, в классе TextWriter определены методы Close() и Flush(), приведенные ниже.virtual void Close()virtual void Flush()
Метод Flush() организует вывод в физическую среду всех данных, оставшихсяв выходном буфере. А метод Close() закрывает записывающий поток и освобождаетего ресурсы.
Классы TextReader и TextWriter реализуются несколькими классами символьных потоков, включая и те, что перечислены ниже. Следовательно, в этих классахпотоков предоставляются методы и свойства, определенные в классах TextReaderи TextWriter.Класс потокаОписаниеStreamReaderПредназначен для ввода символов из байтового потока. Этот класс является оболочкой для байтового потока вводаStreamWriterПредназначен для вывода символов в байтовый поток. Этот класс является оболочкой для байтового потока выводаStringReaderПредназначен для ввода символов из символьной строкиStringWriterПредназначен для вывода символов в символьную строкуДвоичные потоки
Помимо классов байтовых и символьных потоков, имеются еще два класса двоичных потоков, которые могут служить для непосредственного ввода и вывода двоичныхданных — BinaryReader и BinaryWriter. Подробнее о них речь пойдет далее в этойглаве, когда дойдет черед до файлового ввода-вывода.
А теперь, когда представлена общая структура системы ввода-вывода в С#, отведемоставшуюся часть этой главы более подробному рассмотрению различных частей данной системы, начиная с консольного ввода-вывода.Консольный ввод-вывод
Консольный ввод-вывод осуществляется с помощью стандартных потоков, представленных свойствами Console.In, Console.Out и Console.Error. Примеры консольноюввода-вывода были представлены еще в главе 2, поэтому он должен быть вам уже знаком.Как будет показано ниже, он обладает и рядом других дополнительных возможностей.
Но прежде следует еще раз подчеркнуть, что большинство реальных приложенийC# ориентированы не на консольный ввод-вывод в текстовом виде, а на графическийоконный интерфейс для взаимодействия с пользователем, или же они представляютсобой программный код, используемый на стороне сервера. Поэтому часть системыввода-вывода, связанная с консолью, не находит широкого практического применения.И хотя программы, ориентированные на текстовый ввод-вывод, отлично подходят вкачестве учебных примеров, коротких сервисных программ или определенного родапрограммных компонентов, для большинства реальных приложений они не годятся.Чтение данных из потока ввода с консоли