Шрифт:
Главное преимущество метода ReadKey заключается в том, что он предоставляет средства для организации ввода с клавиатуры в диалоговом режиме, поскольку этот ввод не буферизуется построчно. Для того чтобы продемонстрировать данный метод в действии, ниже приведен соответствующий пример программы. // Считать символы, введенные с консоли, используя метод ReadKey. using System; class ReadKeys { static void Main { ConsoleKeyInfo keypress; Console.WriteLine("Введите несколько символов, " + "а по окончании - <Q>."); do { keypress = Console.ReadKey; // считать данные о нажатых клавишах Console.WriteLine(" Вы нажали клавишу: " + keypress.KeyChar); // Проверить нажатие модифицирующих клавиш. if((ConsoleModifiers.Alt & keypress.Modifiers) != 0) Console.WriteLine("Нажата клавиша <Alt>."); if((ConsoleModifiers.Control & keypress.Modifiers) != 0) Console.WriteLine("Нажата клавиша <Control>."); if((ConsoleModifiers.Shift & keypress.Modifiers) != 0) Console.WriteLine("Нажата клавиша <Shift>."); } while(keypress.KeyChar != 'Q'); } }
Вот, например, к какому результату может привести выполнение этой программы. Введите несколько символов, а по окончании - <Q>. а Вы нажали клавишу: а b Вы нажали клавишу: b d Вы нажали клавишу: d А Вы нажали клавишу: А Нажата клавиша <Shift>. В Вы нажали клавишу: В Нажата клавиша <Shift>. С Вы нажали клавишу: С Нажата клавиша <Shift>. • Вы нажали клавишу: • Нажата клавиша <Control>. Q Вы нажали клавишу: Q Нажата клавиша <Shift>.
Как следует из приведенного выше результата, всякий раз, когда нажимается клави ша, метод ReadKey немедленно возвращает введенный с клавиатуры символ. Этим он отличается от упоминавшегося ранее метода Read, в котором ввод выполняется с построчной буферизацией. Поэтому если требуется добиться в программе реакции на ввод с клавиатуры, то рекомендуется выбрать метод ReadKey. Запись данных в поток вывода на консоль
Потоки Console.Out и Console.Error являются объектами типа TextWriter. Вывод на консоль проще всего осуществить с помощью методов Write и WriteLine, с которыми вы уже знакомы. Существуют варианты этих методов для вывода данных каждого из встроенных типов. В классе Console определяются его соб ственные варианты метода Write и WriteLine, и поэтому они могут вызываться непосредственно для класса Console, как это было уже не раз показано на страницах данной книги. Но при желании эти и другие методы могут быть вызваны и для класса TextWriter, который является базовым для потоков Console.Out и Console.Error.
Ниже приведен пример программы, в котором демонстрируется вывод в потоки Console.Out и Console.Error. По умолчанию данные в обоих случаях выводятся на консоль. // Организовать вывод в потоки Console.Out и Console.Error. using System; class ErrOut { static void Main { int a=10, b=0; int result; Console.Out.WriteLine("Деление на нуль приведет " + "к исключительной ситуации."); try { result = a / b; // сгенерировать исключение при попытке деления на нуль } catch(DivideByZeroException exc) { Console.Error.WriteLine(exc.Message); } } }
При выполнении этой программы получается следующий результат. Деление на нуль приведет к исключительной ситуации. Попытка деления на нуль.
Начинающие программисты порой испытывают затруднения при использова нии потока Console.Error. Перед ними невольно встает вопрос: если оба потока, Console.Out и Console.Error, по умолчанию выводят результат на консоль, то за чем нужны два разных потока вывода? Ответ на этот вопрос заключается в том, что стандартные потоки могут быть переадресованы на другие устройства. Так, поток Console.Error можно переадресовать в выходной файл на диске, а не на экран. Это, например, означает, что сообщения об ошибках могут быть направлены в файл журна ла регистрации, не мешая выводу на консоль. И наоборот, если вывод на консоль пере адресуется, а вывод сообщений об ошибках остается прежним, то на консоли появятся сообщения об ошибках, а не выводимые на нее данные. Мы еще вернемся к вопросу переадресации после рассмотрения файлового ввода-вывода. Класс FileStream и байтовый ввод-вывод в файл
В среде .NET Framework предусмотрены классы для организации ввода-вывода в файлы. Безусловно, это в основном файлы дискового типа. На уровне операционной системы файлы имеют байтовую организацию. И, как следовало ожидать, для ввода и вывода байтов в файлы имеются соответствующие методы. Поэтому ввод и вывод в файлы байтовыми потоками весьма распространен. Кроме того, байтовый поток вво да или вывода в файл может быть заключен в соответствующий объект символьного потока. Операции символьного ввода-вывода в файл находят применение при обра ботке текста. О символьных потоках речь пойдет далее в этой главе, а здесь рассматри вается байтовый ввод-вывод.
Для создания байтового потока, привязанного к файлу, служит класс FileStream. Этот класс является производным от класса Stream и наследует всего его функции.
Напомним, что классы потоков, в том числе и FileStream, определены в простран стве имен System.IO. Поэтому в самом начале любой использующей их программы обычно вводится следующая строка кода. using System.IO; Открытие и закрытие файла
Для формирования байтового потока, привязанного к файлу, создается объект класса FileStream. В этом классе определено несколько конструкторов. Ниже при веден едва ли не самый распространенный среди них: FileStream(string путь, FileMode режим)
где путь обозначает имя открываемого файла, включая полный путь к нему; а ре жим — порядок открытия файла. В последнем случае указывается одно из значений, определяемых в перечислении FileMode и приведенных в табл. 14.4. Как правило, этот конструктор открывает файл для доступа с целью чтения или записи. Исключе нием из этого правила служит открытие файла в режиме FileMode.Append, когда файл становится доступным только для записи.
Таблица 14.4. Значения из перечисления FileMode Значение Описание FileMode.Append Добавляет выводимые данные в конец файла FileMode.Create Создает новый выходной файл. Существующий файл с таким же именем будет разрушен FileMode.CreateNew Создает новый выходной файл. Файл с таким же именем не должен существовать FileMode.Open Открывает существующий файл FileMode.OpenOrCreate Открывает файл, если он существует. В противном случае создает новый файл FileMode.Truncate Открывает существующий файл, но сокращает его длину до нуля