Литмир - Электронная Библиотека
A
A

Пусть имеется новый проект консольного приложения под названием

FileStreamApp
(и в файле кода C# импортировано пространство имен
System.IO
и
System.Text
). Целью будет запись простого текстового сообщения в новый файл по имени
myMessage.dat
. Однако с учетом того, что
FileStream
может оперировать только с низкоуровневыми байтами, объект типа
System.String
придется закодировать в соответствующий байтовый массив. К счастью, в пространстве имен
System.Text
определен тип
Encoding
, предоставляющий члены, которые кодируют и декодируют строки в массивы байтов.

После кодирования байтовый массив сохраняется в файле с помощью метода

FileStream.Write()
. Чтобы прочитать байты обратно в память, понадобится сбросить внутреннюю позицию потока (посредством свойства
Position
) и вызвать метод
ReadByte()
. Наконец, на консоль выводится содержимое низкоуровневого байтового массива и декодированная строка. Ниже приведен полный код:

using System;

using System.IO;

using System.Text;

<b>// He забудьте импортировать пространства имен System.Text и System.IO.</b>

Console.WriteLine(&quot;***** Fun with FileStreams *****\n&quot;);

<b>// Получить объект FileStream.</b>

using(FileStream fStream = File.Open(&quot;myMessage.dat&quot;,

  FileMode.Create))

{

<b>  // Закодировать строку в виде массива байтов.</b>

  string msg = &quot;Hello!&quot;;

  byte[] msgAsByteArray = Encoding.Default.GetBytes(msg);

<b>  // Записать byte[] в файл.</b>

  fStream.Write(msgAsByteArray, 0, msgAsByteArray.Length);

<b>  // Сбросить внутреннюю позицию потока.</b>

  fStream.Position = 0;

<b>  // Прочитать byte[] из файла и вывести на консоль.</b>

  Console.Write(&quot;Your message as an array of bytes: &quot;);

  byte[] bytesFromFile = new byte[msgAsByteArray.Length];

  for (int i = 0; i &lt; msgAsByteArray.Length; i++)

  {

    bytesFromFile[i] = (byte)fStream.ReadByte();

    Console.Write(bytesFromFile[i]);

  }

<b>  // Вывести декодированное сообщение.</b>

  Console.Write(&quot;\nDecoded Message: &quot;);

  Console.WriteLine(Encoding.Default.GetString(bytesFromFile));

  Console.ReadLine();

}

File.Delete(&quot;myMessage.dat&quot;);

В приведенном примере не только производится наполнение файла данными, но также демонстрируется основной недостаток прямой работы с типом

FileStream
: необходимость оперирования низкоуровневыми байтами. Другие производные от
Stream
типы работают в похожей манере. Например, чтобы записать последовательность байтов в область памяти, понадобится создать объект
MemoryStream
.

Как упоминалось ранее, в пространстве имен

System.IO
доступно несколько типов для средств чтения и записи, которые инкапсулируют детали работы с типами, производными от
Stream
.

Работа с типами StreamWriter и StreamReader

Классы

StreamWriter
и
StreamReader
удобны всякий раз, когда нужно читать или записывать символьные данные (например, строки). Оба типа по умолчанию работают с символами Unicode; тем не менее, это можно изменить за счет предоставления должным образом сконфигурированной ссылки на объект
System.Text.Encoding
. Чтобы не усложнять пример, предположим, что стандартная кодировка Unicode вполне устраивает.

Класс

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

Класс

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

Чтобы содействовать пониманию основных возможностей записи в классах

StreamWriter
и
StringWriter
, в табл. 20.8 перечислены основные члены абстрактного базового класса
TextWriter
.

Язык программирования C#9 и платформа .NET5 - _134.png

На заметку! Вероятно, последние два члена класса

TextWriter
покажутся знакомыми. Вспомните, что тип
System.Console
имеет члены
Write()
и
WriteLine()
, которые выталкивают текстовые данные на стандартное устройство вывода. В действительности свойство
Console.In
является оболочкой для объекта
TextWriter
, a
Console.Out
— для
TextWriter
.

Производный класс

StreamWriter
предоставляет подходящую реализацию методов
Write()
,
Close()
и
Flush()
, а также определяет дополнительное свойство
AutoFlush
. Установка этого свойства в
true
заставляет
StreamWriter
выталкивать данные при каждой операции записи. Имейте в виду, что за счет установки
AutoFlush
в
false
можно достичь более высокой производительности, но по завершении работы с объектом
StreamWriter
должен быть вызван метод
Close()
.

367
{"b":"847442","o":1}