Классы StreamWriter и StreamReader
76C# и .NET --- Многопоточность и файлы --- Классы StreamWriter и StreamReader
Классы StreamWriter и StreamReader удобны во всех случаях, когда нужно читать или записывать символьные данные (например, строки). Оба типа работают по умолчанию с символами Unicode; однако это можно изменить предоставлением правильно сконфигурированной ссылки на объект System.Text.Encoding. Чтобы не усложнять пример, предположим, что кодировка по умолчанию Unicode вполне устраивает.
Класс StreamReader, унаследован от абстрактного класса по имени TextReader. Базовый класс предлагает очень ограниченный набор функциональности каждому из его наследников, в частности — возможность читать и "заглядывать" (peek) в символьный поток.
Класс StreamWriter наследуется от абстрактного базового класса по имени TextWriter. В этом классе определены члены, позволяющие производным типам записывать текстовые данные в заданный символьный поток.
Чтобы приблизить вас к пониманию основных возможностей записи классов StreamWriter и StringWriter, ниже представлены описания основных членов абстрактного базового класса TextWriter:
- Close()
Этот метод закрывает объект-писатель и освобождает все связанные с ним ресурсы. В процессе автоматически сбрасывается буфер (опять-таки, этот член функционально эквивалентен методу Dispose())
- Flush ()
Этот метод очищает все буферы текущего объекта-писателя и записывает все буферизованные данные на лежащее в основе устройство, однако, не закрывает его
- NewLine
Это свойство задает константу перевода строки для унаследованного класса писателя. По умолчанию ограничителем строки в Windows является возврат каретки, за которым следует перевод строки (\r\n)
- Write()
Этот перегруженный метод записывает данные в текстовый поток без добавления константы новой строки
- WriteLine()
Этот перегруженный метод записывает данные в текстовый поток с добавлением константы новой строки
Последние два члена класса TextWriter, скорее всего, покажутся знакомыми. Если помните, тип System.Console имеет члены Write() и WriteLine(), которые выталкивают текстовые данные на стандартное устройство вывода. Фактически свойство Console.In хранит TextReader, a Console.Out — TextWriter.
Унаследованный класс StreamWriter предоставляет соответствующую реализацию методов Write(), Close() и Flush(), а также определяет дополнительное свойство AutoFlush. Когда это свойство установлено в true, оно заставляет StreamWriter выталкивать данные при каждой операции записи. Имейте в виду, что можно обеспечить более высокую производительность, установив AutoFlush в false, но при этом всегда вызывать Close() по завершении работы с StreamWriter.
Используя классы StreamReader и StreamWriter, не нужно беспокоиться о применяемой в файле кодировке (формате текста). К числу возможных кодировок относятся ASCII (1 байт на каждый символ) и Unicode с его разновидностями UTF7, UTF8 и UTF32. Текстовые файлы в системах Windows 9х всегда используют кодировку ASCII, потому что в них Unicode не поддерживается. Но поскольку в ОС Windows NT, 2000, XP, 2003, Vista, Windows Server 2008 и Windows 7 кодировка Unicode поддерживается, теоретически текстовые файлы могут содержать данные не ASCII, а Unicode, UTF7, UTF8 и UTF32.
По соглашению, если файл имеет формат ASCII, он будет просто содержать текст. Если же файл имеет какой-то из форматов Unicode, об этом будет обязательно сообщаться в первых двух или трех байтах файла, в которых устанавливаются определенные комбинации значений для обозначения используемого в файле формата.
Эти байты называют маркерами байтовой кодировки. При открытии файла в любом стандартном приложении Windows, таком как Notepad или WordPad, об этом беспокоиться не нужно, потому что эти приложения различают кодировку, и будут автоматически читать файл правильным образом. Точно так же обстоит дело и с классом StreamReader, который умеет правильно считывать файл в любом из этих форматов, и классом StreamWriter, умеющим форматировать записываемый файл с использованием любой запрашиваемой кодировки. Если для чтения и записи текстового файла планируется использовать класс FileStream, то об этих вещах необходимо заботиться самостоятельно.