Как упоминалось ранее, стандартные потоки, например Console.In, могут быть переадресованы. И чаще всего они переадресовываются в файл. Когда стандартный поток переадресовывается, то вводимые или выводимые данные направляются в новый поток в обход устройств, используемых по умолчанию. Благодаря переадресации стан дартных потоков в программе может быть организован ввод команд из дискового фай ла, создание файлов журнала регистрации и даже чтение входных данных из сетевого соединения.
Переадресация стандартных потоков достигается двумя способами. Прежде всего, это делается при выполнении программы из командной строки с помощью операто ров < и >, переадресовывающих потоки Console.In и Console.Out соответственно. Допустим, что имеется следующая программа. using System; class Test { static void Main { Console.WriteLine("Это тест."); } }
Если выполнить эту программу из командной строки Test > log
то символьная строка "Это тест." будет выведена в файл log. Аналогичным образом переадресуется ввод. Но для переадресации ввода указываемый источник входных дан ных должен удовлетворять требованиям программы, иначе она "зависнет".
Операторы < и >, выполняющие переадресацию из командной строки, не являются составной частью С#, а предоставляются операционной системой. Поэтому если в ра бочей среде поддерживается переадресация ввода-вывода, как, например, в Windows, то стандартные потоки ввода и вывода можно переадресовать, не внося никаких изме нений в программу. Тем не менее существует другой способ, позволяющий осущест влять переадресацию стандартных потоков под управлением самой программы. Для этого служат приведенные ниже методы SetIn, SetOut и SetError, являю щиеся членами класса Console. static void SetIn(TextReader новый_поток_ввода) static void SetOut(TextWriter новый_поток_вывода) static void SetError(TextWriter новый_поток_сообщений_об_ошибках)
Таким образом, для переадресации ввода вызывается метод SetIn с указанием требуемого потока. С этой целью может быть использован любой поток ввода, при условии, что он является производным от класса TextReader. А для переадресации вывода вызывается метод SetOut с указанием требуемого потока вывода, который должен быть также производным от класса TextReader. Так, для переадресации вы вода в файл достаточно указать объект класса FileStream, заключенный в оболочку класса StreamWriter. Соответствующий пример программы приведен ниже. // Переадресовать поток Console.Out. using System; using System.IO; class Redirect { static void Main { StreamWriter log_out = null; try { log_out = new StreamWriter("logfile.txt"); // Переадресовать стандартный вывод в файл logfile.txt. Console.SetOut(log_out); Console.WriteLine("Это начало файла журнала регистрации."); for(int i=0; i<10; i++) Console.WriteLine(i); Console.WriteLine("Это конец файла журнала регистрации."); } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода\n" + exc.Message); } finally { if(log_out != null) log_out.Close; } } }
При выполнении этой программы на экран ничего не выводится, но файл logfile.txt будет содержать следующее. Это начало файла журнала регистрации. 0 1 2 3 4 5 6 7 8 9 Это конец файла журнала регистрации.
Попробуйте сами поупражняться в переадресации других встроенных потоков. Чтение и запись двоичных данных
В приведенных ранее примерах демонстрировались возможности чтения и записи байтов или символов. Но ведь имеется также возможность (и ею пользуются часто) чи тать и записывать другие типы данных. Например, можно создать файл, содержащий данные типа int, double или short. Для чтения и записи двоичных значений встро енных в C# типов данных служат классы потоков BinaryReader и BinaryWriter. Используя эти потоки, следует иметь в виду, что данные считываются и записываются во внутреннем двоичном формате, а не в удобочитаемой текстовой форме. Класс BinaryWriter
Класс BinaryWriter служит оболочкой, в которую заключается байтовый поток, управляющий выводом двоичных данных. Ниже приведен наиболее часто употребляе мый конструктор этого класса: BinaryWriter(Stream output)
где output обозначает поток, в который выводятся записываемые данные. Для записи в выходной файл в качестве параметра output может быть указан объект, создавае мый средствами класса FileStream. Если же параметр output оказывается пустым, то генерируется исключение ArgumentNullException. А если поток, определяемый параметром output, не был открыт для записи данных, то генерируется исключение ArgumentException. По завершении вывода в поток типа BinaryWriter его нужно закрыть. При этом закрывается и базовый поток.