Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

Работа с типами StringWriter и StringReader

Используя типы StringWriter и StringReader, вы можете обращаться с текстовой информацией, как с потоком символов в памяти. Это может оказаться полезным тогда, когда необходимо добавить символьную информацию в соответствующий буфер. В следующем примере блок строковых данных записывается в объект StringWriter, а не в файл на локальном жестком диске.

static void Main(string[] args) {

 Console.WriteLine("*** Забавы с StringWriter/StringReader ***\n");

 // Создание StringWriter и вывод символьных данных в память.

 StringWriter strWriter = new StringWriter();

 strWriter.WriteLine("He забыть о дне рождения мамы…");

 strWriter.Close();

 // Получение копии содержимого (сохраненного в строке) и

 // вывод на консоль.

 Console.WriteLine("Содержимое StringWriter:\n{0}", strWriter);

}

Ввиду того, что и StringWriter, и StreamWriter получаются из одного и того же базового класса (TextWriter), для них используется приблизительно одинаковая программная логика записи. Однако ввиду самой своей природы, класс StringWriter позволяет извлечь объект System.Text.StringBuilder с помощью метода GetStringBuilder().

static void Main(string[] args) {

 Соnsоlе.WriteLine("*** Забавы с StringWriter/StringReader ***\n'');

 …

 // Создание StringWriter и вывод символьных данных в память.

 StringWriter strWriter = new StringWriter();

 …

 // Получение внутреннего StringBuilder.

 StringBuilder sb = strWriter.GetStringBuilder();

 sb.Insert(0, "Эй!! ");

 Console.WriteLine("-› {0}", sb.ToString());

 sb.Remove(0, "Эй!! ".Length);

 Console.WriteLine("-› {0}", sb.ToString());

}

Чтобы прочитать данные из символьного потока, используйте соответствующий тип StringReader, который (в соответствии с ожиданиями) функционирует так же, как и родственный ему класс StreamReader. Фактически класс StringReader просто переопределяет наследуемые члены, чтобы обеспечить чтение из блока символьных данных, а не из файла.

static void Main(string[] args) {

 Console.WriteLine("*** Забавы с StringWriter/StringReader ***\n");

 // Создание StringWriter и вывод символьных данных в память.

 StringWriter strWriter = new StringWriter();

 …

 // Чтение данных из StringWriter.

 StringReader strReader = new StringReader(writer.ToString());

 string input = null;

 while ((input = strReader.ReadLine()) != null) {

  Console.WriteLine(input);

 }

 strReader.Close();

}

Исходный код. Проект StringWriterReaderApp размещен в подкаталоге, соответствующем главе 16.

Работа с BinaryWriter и BinaryReader

И последним из рассмотренных здесь средств чтения/записи будут BinaryReader и BinaryWriter, которые получаются непосредственно из System.Object. Эти типы позволяют читать и записывать дискретные типы данных в соответствующий поток в компактном двоичном формате. Класс BinaryWriter определяет чрезвычайно перегруженный метод Write(), позволяющий поместить тип данных в соответствующий поток. Вдобавок к Write(), класс BinaryWriter предлагает дополнительные члены, позволяющие получить или установить тип, производный от Stream, и обеспечить поддержку прямого доступа к данным (табл. 16.9).

Таблица 16.9. Основные члены BinaryWriter 

Член

Описание

BaseStream

Свойство, доступное только для чтения. Обеспечивает доступ к потоку, используемому с объемом BinaryWriter

Close()

Метод, завершающий двоичный поток

Flush()

Метод, выполняющий очистку двоичного потока

Seek()

Метод, устанавливающий указатель позиции в текущем потоке

Write()

Метод, записывающий значение в текущий поток

Класс BinaryReader дополняет функциональные возможности, предлагаемые членами BinaryWriter (табл. 16.10).

Таблица 16.10. Основные Члены BinaryReader

Член

Описание

BaseStream

Свойство, доступное только для чтения. Обеспечивает доступ к потоку, используемому с объектом BinaryReader

Close()

Метод, завершающий двоичный поток чтения

PeekChar()

Метод, возвращающий следующий доступный символ без фактического смещения указателя позиции в потоке

Read()

Метод, считывающий заданное множество байтов или символов и запоминающий их во входном массиве

ReadXXX()

Класс BinaryReader определяет множество методов ReadXXX(), "захватывающих" следующий тип из потока (ReadBoolean(), ReadByte(), ReadInt32() и т.д.)

В следующем примере в новый файл *.dat записывается целый ряд типов данных,

static void Main(string[] args) {

 // Открытие сеанса двоичной записи в файл.

 FileInfo f = new FileInfo("BinFile.dat");

 BinaryWriter bw = new BinaryWriter(f.OpenWrite());

 // Печать информации о типе BaseStream.

 // (в данном случае это System.IO.FileStream) .

 Console.WriteLine("Базовый поток: {0}", bv.BaseStream);

 // Создание порции данных для сохранения в файле.

 double aDouble = 1234.67;

 int anInt = 34567;

 char[] aCharArray = { 'A', 'В', 'С'};

 // Запись данных.

 bw.Write(aDouble);

 bw.Write(anInt);

 bw.Write(aCharArray);

 bw.Close();

}

Обратите внимание на то, что объект FileStream, возвращенный из FileInfo.OpenWrite(), передается конструктору типа BinaryWriter. С помощью такого подхода очень просто выполнить "расслоение" потока перед записью данных. Следует осознавать, что конструктор BinaryWriter способен принять любой тип, производный от Stream (например, FileStream, MemoryStream или BufferedStream). Поэтому, если нужно записать двоичные данные, например, в память, просто укажите подходящий объект MemoryStream.

Для чтения данных из файла BinFile.dat тип BinaryReader предлагает множество опций. Ниже мы используем PeekChar(), чтобы выяснить, имеет ли поток еще данные, и в том случае, когда он их имеет, использовать ReadByte() для получения значения. Обратите внимание на то, что байты форматируются в шестнадцатиричном виде и между ними вставляются семь пробелов.

static void Main(string[] args) {

 // Открытие сеанса двоичной записи в файл.

 FileInfo f = new FileInfo("BinFile.dat");

 …

 // Чтение данных в виде "сырых" байтов.

 BinaryReader br = new BinaryReader(f.OpenRead());

 int temp = 0;

 while (br.PeekChar() != -1) {

  Console.Write("{0,7:x}", br.ReadByte());

  if (++temp == 4) {

   // Запись каждых 4 байтов в виде новой строки.

Console.WriteLine();

   temp = 0;

  }

 Console.WriteLine();

 }

}

Исходный код. Проект BinaryWriterReader размещен в подкаталоге, соответствующем главе 16.

Вывод этой программы показан на рис. 16.9.

Рис. 16.9. Чтение байтов из двоичного файла