Язык программирования C#9 и платформа .NET5
Часть 367 из 642 Информация о книге
Пусть имеется новый проект консольного приложения под названием
(и в файле кода C# импортировано пространство именFileStreamAppи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("***** Fun with FileStreams *****\n");<b>// Получить объект FileStream.</b>using(FileStream fStream = File.Open("myMessage.dat",FileMode.Create)){<b> // Закодировать строку в виде массива байтов.</b>string msg = "Hello!";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("Your message as an array of bytes: ");byte[] bytesFromFile = new byte[msgAsByteArray.Length];for (int i = 0; i < msgAsByteArray.Length; i++){bytesFromFile[i] = (byte)fStream.ReadByte();Console.Write(bytesFromFile[i]);}<b> // Вывести декодированное сообщение.</b>Console.Write("\nDecoded Message: ");Console.WriteLine(Encoding.Default.GetString(bytesFromFile));Console.ReadLine();}File.Delete("myMessage.dat");В приведенном примере не только производится наполнение файла данными, но также демонстрируется основной недостаток прямой работы с типом
: необходимость оперирования низкоуровневыми байтами. Другие производные отFileStreamтипы работают в похожей манере. Например, чтобы записать последовательность байтов в область памяти, понадобится создать объектStream.MemoryStreamКак упоминалось ранее, в пространстве имен
доступно несколько типов для средств чтения и записи, которые инкапсулируют детали работы с типами, производными отSystem.IO.StreamРабота с типами StreamWriter и StreamReader
Классы
иStreamWriterудобны всякий раз, когда нужно читать или записывать символьные данные (например, строки). Оба типа по умолчанию работают с символами Unicode; тем не менее, это можно изменить за счет предоставления должным образом сконфигурированной ссылки на объектStreamReader. Чтобы не усложнять пример, предположим, что стандартная кодировка Unicode вполне устраивает.System.Text.EncodingКласс
является производным от абстрактного класса по имениStreamReader, как и связанный с ним типTextReader(обсуждается далее в главе). Базовый классStringReaderпредоставляет каждому из своих наследников ограниченный набор функциональных средств, в частности возможность читать и "заглядывать" в символьный поток.TextReaderКласс
(а такжеStreamWriter, который будет рассматриваться позже) порожден от абстрактного базового класса по имениStringWriter, в котором определены члены, позволяющие производным типам записывать текстовые данные в текущий символьный поток.TextWriterЧтобы содействовать пониманию основных возможностей записи в классах
иStreamWriter, в табл. 20.8 перечислены основные члены абстрактного базового классаStringWriter.TextWriterНа заметку! Вероятно, последние два члена класса
покажутся знакомыми. Вспомните, что типTextWriterимеет членыSystem.ConsoleиWrite(), которые выталкивают текстовые данные на стандартное устройство вывода. В действительности свойствоWriteLine()является оболочкой для объектаConsole.In, aTextWriter— дляConsole.Out.TextWriterПроизводный класс
предоставляет подходящую реализацию методовStreamWriter,Write()иClose(), а также определяет дополнительное свойствоFlush(). Установка этого свойства вAutoFlushзаставляетtrueвыталкивать данные при каждой операции записи. Имейте в виду, что за счет установкиStreamWriterвAutoFlushможно достичь более высокой производительности, но по завершении работы с объектомfalseдолжен быть вызван методStreamWriter.Close()
