Переадресация стандартных потоков



 

Как упоминалось ранее, стандартные потоки, например 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("Ошибка ввода-вывода" + 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 его нужно закрыть. При этом закрывается и базовый поток.

В классе BinaryWriter определены методы, предназначенные для записи данных всех встроенных в C# типов. Некоторые из этих методов перечислены в табл. 14.5. Обратите внимание на то, что строковые данные типа string записываются во внутреннем формате с указанием длины строки. Кроме того, в классе BinaryWriter определены стандартные методы Close() и Flush(), действующие аналогично описанному выше.

 

Таблица 14.5. Наиболее часто используемые методы, определенные в классе BinaryWriter

 

Метод - Описание

 

void Write(sbyte value) - Записывает значение типа sbyte со знаком

void Write(byte value) - Записывает значение типа byte без знака

void Write(byte[] buffer) - Записывает массив значений типа byte

void Write(short value) - Записывает целочисленное значение типа short (короткое целое)

void Write(ushort value) - Записывает целочисленное значение типа ushort (короткое целое без знака)

void Write (int value) - Записывает целочисленное значение типа int

void Write(uint value) - Записывает целочисленное значение типа uint (целое без знака)

void Write(long value) - Записывает целочисленное значение типа long (длинное целое)

void Write(ulong value) - Записывает целочисленное значение типа ulong (длинное целое без знака)

void Write(float value)  - Записывает значение типа float (с плавающей точкой одинарной точности)

void Write(double value) - Записывает значение типа double (с плавающей точкой двойной точности)

void Write(decimal value) - Записывает значение типа decimal (с двумя десятичными разрядами после запятой)

void Write(char ch) - Записывает символ

void Write (char[] buffer) - Записывает массив символов

void Write(string value) Записывает строковое значение типа string, представленное во внутреннем формате с указанием длины строки

 

 

Класс BinaryReader

 

Класс BinaryReader служит оболочкой, в которую заключается байтовый поток, управляющий вводом двоичных данных. Ниже приведен наиболее часто употребляемый конструктор этого класса:

 

BinaryReader(Stream input)

 

где input обозначает поток, из которого вводятся считываемые данные. Для чтения из входного файла в качестве параметра input может быть указан объект, создаваемый средствами класса FileStream. Если же поток, определяемый параметром input , не был открыт для чтения данных или оказался недоступным по иным причинам, то генерируется исключение ArgumentException. По завершении ввода из потока типа BinaryReader его нужно закрыть. При этом закрывается и базовый поток.

В классе BinaryReader определены методы, предназначенные для чтения данных всех встроенных в C# типов. Некоторые из этих методов перечислены в табл. 14.6. Следует, однако, иметь в виду, что в методе Readstring() считывается символьная строка, хранящаяся во внутреннем формате с указанием ее длины. Все методы данного класса генерируют исключение IOException, если возникает ошибка ввода. Кроме того, могут быть сгенерированы и другие исключения.

 

Таблица 14.6. Наиболее часто используемые методы, определенные в классе BinaryReader

 

Метод - Описание

 

bool ReadBoolean() - Считывает значение логического типа bool

byte ReadByte() - Считывает значение типа byte

sbyte ReadSByte() - Считывает значение типа sbyte

byte[] ReadBytes(int  count) -  Считывает количество count байтов и возвращает их в виде массива

char ReadChar() - Считывает значение типа char

char[] ReadChars(int  count) -  Считывает количество count символов и возвращает их в виде массива

decimal ReadDecimal() - Считывает значение типа decimal

double ReadDouble() - Считывает значение типа double

float ReadSingle() - Считывает значение типа float

short Readlnt16() - Считывает значение типа short

int Readlnt32() - Считывает значение типа int

long Readlnt64() - Считывает значение типа long

ushort ReadUIntl6() - Считывает значение типа ushort

uint ReadUInt32() - Считывает значение типа uint

ulong ReadUInt64() - Считывает значение типа ulong

string ReadString( ) - Считывает значение типа string, представленное во внутреннем двоичном формате с указанием длины строки. Этот метод следует использовать для считывания строки, которая была записана средствами класса BinaryWriter

 

В классе BinaryWriter определены также три приведенных ниже варианта метода Read().

При неудачном исходе операции чтения эти методы генерируют исключение IOException. Кроме того, в классе BinaryReader определен стандартный метод Close().

 

Метод - Описание

int Read() - Возвращает целочисленное представление следующего доступного символа из вызывающего потока ввода. При обнаружении конца файла возвращает значение -1

int Read(byte [] buffer, int offset, int  count)  -  Делает попытку прочитать количество count байтов в массив buffer, начиная с элемента buffer[offset ], и возвращает количество успешно считанных байтов

int Read(char[]buffer,  int offset, int  count) -  Делает попытку прочитать количество count символов в массив buffer , начиная с элемента buffer[offset ], и возвращает количество успешно считанных символов

 

 


Дата добавления: 2019-02-12; просмотров: 283; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!