Иллюстрированный самоучитель по VB.NET

         

TextReader, TextWriter и производные классы


Двоичные потоки чтения/записи хорошо подходят для случаев, когда программисту точно известен порядок следования данных в двоичном формате, но прочитать полученный файл бывает непросто. Таким образом, для хранения обычного текста в файле лучше поискать другой вариант. В этой стандартной ситуации вместо пары BinaryReader/BinaryWriter следует использовать пару StreamReader/StreamWriter. По функциональным возможностям классы StreamReader и StreamWriter близки к традиционным средствам последовательного доступа к файлам из прежних версий VB (если не считать того, что в этих классах появилась поддержка Unicode). В классе StreamReader помимо метода Read также имеется удобный метод ReadToEnd, позволяющий прочитать весь файл за одну операцию.

Обратите внимание, что эти классы объявлены производными от абстрактных классов TextReader и TextWriter, а не от Stream. Эти абстрактные классы, объявленные с атрибутом Must Inherit, содержат общие средства чтения/записи текста. Их методы перечислены в табл. 9.11 и 9.12.

Таблица 9.11. Основные методы класса TextReader

Метод



Описание

Close Закрывает существующий поток TextReader и освобождает все системные ресурсы, связанные с ним
Peek

Возвращает следующий символ в потоке без смещения указателя текущей позиции

Read Читает один символ из входного потока. Перегруженная версия читает в символьный массив определенное количество символов начиная с заданной позиции
ReadLine Читает символы до комбинации CR+LF и возвращает их в виде строкового значения. Если текущая позиция находится в конце файла, метод возвращает Nothing
ReadToEnd Читает все символы от текущей позиции до конца TextReader и возвращает их в виде одной строки (метод особенно удобен при работе с небольшими файлами)

Таблица 9.12. Основные методы класса TextWriter

Метод

Описание

Close Закрывает существующий поток TextWriter и освобождает все системные ресурсы, связанные с ним
Write Перегруженные версии метода позволяют записывать в поток любые базовые типы данных в текстовом формате
WriteLine Перегружается для записи в поток любых базовых типов данных в текстовом формате, за которыми записывается комбинация CR+LF
<


Свойства Console.In и Console.Out используемые при консольном вводе-выводе, в дей- ствительности являются экземплярами классов TextReader и TextWriter. Методы Соп-sole.Setln и Console.SetOut позволяют перенаправить стандартный ввод и вывод любым классам *Reader и 'Writer соответственно.

Поскольку классы TextReader и TextWriter являются абстрактными, программы работают с конкретными реализациями StreamReader и StreamWriter. Как и в случае с классами BinaryReader и BinaryWriter, при создании объектов StreamReader и StreamWriter конструктору обычно передается существующий объект потока:

myFile = New FileStreamtfileName.FileMode.Open, FileAccess.Read)

textFile= New StreamReader(myFile)

Для получения объекта также можно воспользоваться методами класса File. Пример неявного создания объекта StreamReader при создании файлового потока продемонстрирован ниже:

Dim aStreamReader As StreamReader

aStreamReader = File.OpenText ("sample.txt")

Объекты класса StreamWriter создаются аналогичным образом:

Dim aStreamWriter As StreamWriter

aStreamWriter = File.CreateText ("test.txt")

Данные записываются в поток методами Write и WriteLine. Что касается чтения, в вашем распоряжении два способа. В наиболее распространенном варианте программа в цикле читает строки до тех пор, пока очередная прочитанная строка не окажется равной Nothing. В программе это выглядит примерно так:

Dim s As String Do

s = theStreamReader.ReadLine If Not s Is Nothing Then

' Выполнить нужные действия с s.

' Например, вызвать Console.WriteLine(s).

End If

Loop Untils Is Nothing

Также можно воспользоваться методом Peek и проверить, равен ли следующий читаемый символ -1 (признак конца файла):

Do Until theStreamReader.Peek = -1

В качестве примера использования класса TextReader ниже приводится простая процедура, предназначенная для вывода текстового файла на экран. Обратите внимание: в строках 5-17 весь важный код заключен в блок Try-Catch-Finally. В этом блоке программа пытается закрыть открытый поток независимо от того, что произошло при операциях с ним.


Как упоминалось выше, перед вызовом Cl ose в строке 16 сначала необходимо убедиться в том, что поток был успешно создан. Также обратите внимание на то, как в строке 14 к инициируемому исключению добавляется содержательное сообщение. В реальной программе следовало бы определить новый класс исключения (за подробностями обращайтесь к главе 7).

1 Sub DisplayTextFile(ByVal fName As String)

2 Dim myFile As FileStream

3 Dim textFile As StreamReader

4 Dim stuff As String

5 Try

6 myFile = New FileStream(fName.FileMode.Open, FileAccess.Read)

7 textFile = New StreamReader(myFile)

8 stuff = textFile.ReadLine()

9 Do Until stuff Is Nothing

10 Console.WriteLine(stuff)

11 stuff = textFile.ReadLine()

12 Loop

13 Catch e As Exception

14 Throw New Exception("If the file existed.it was closed")

15 Finally

16 If Not (myFile Is Nothing)Then myFile.Close()

17 End Try

18 End Sub

19 End Module

В общем случае отдельные строки файла можно сохранить в динамическом массиве ArrayList (если, конечно, количество строк относительно невелико). Для этого достаточно внести минимальные изменения в предыдущую программу. В заголовок процедуры добавляется новый параметр:

Sub DisplayTextFile(ByVal fName As String,ByVal where As ArrayList)

Строка 10 приводится к следующему виду:

where, Add(stuff)




Содержание раздела