Символьные потоки StreamWriter и StreamReader работают с Unicode-символами1(cуществует возможность изменить используемую кодировку с помощью объекта System.Text.Encoding),следовательно, ими удобнее всего пользоваться для работы с файлами, предназначенными для восприятия человеком. Эти потоки являются наследниками классов TextWriter и TextReader соответственно, которые обеспечивают их большей частью функциональности. В табл. 11.6 и 11.7 приведены наиболее важные элементы этих классов. Как видите, произвольный доступ для текстовых файлов не поддерживается.
Таблица 11.6. Наиболее важные элементы базового класса TextWriter
Элемент Описание
Close Закрыть файл и освободить связанные с ним ресурсы. Если в процессе записи
используется буфер, он будет автоматически очищен
Flush Очистить все буферы для текущего файла и записать накопленные в них данные
в место их постоянного хранения. Сам файл при этом не закрывается
NewLine Используется для задания последовательности символов, означающих начало новой
строки. По умолчанию используется последовательность «возврат каретки» —
|
|
«перевод строки» (\г\n)
Write Записать фрагмент текста в поток
WriteLine Записать строку в поток и перейти на другую строку
Таблица 11.7. Наиболее важные элементы класса TextReader
Элемент Описание
Peek Возвратить следующий символ, не изменяя позицию указателя в файле
Read Считать данные из входного потока
ReadBlock Считать из входного потока указанное пользователем количество символов и
записать их в буфер, начиная с заданной позиции
ReadLine Считать строку из текущего потока и возвратить ее как значение типа string. Пустая
строка (null) означает конец файла (EOF)
ReadToEnd Считать все символы до конца потока, начиная с текущей позиции, и возвратить
считанные данные как одну строку типа string
Вы уже знакомы с некоторыми методами, приведенными в этих таблицах: на протяжении всей книги постоянно использовались методы чтения из текстовых потоков и записи в текстовые потоки, но не для дисковых файлов, а для консоли, которая является их частным случаем.
В листинге 11.3 создается текстовый файл, в который записываются две строки. Вторая строка формируется из преобразованных численных значений переменных и поясняющего текста. Содержимое файла можно посмотреть в любом текстовом редакторе. Файл создается в том же каталоге, куда среда записывает исполняемый файл. По умолчанию это каталог...\ConsoleApplication1\bin\Debug.
Листинг 11.3. Вывод в текстовый файл
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
try
{
StreamWriter f = new StreamWriter("text.txt");
f.WriteLine("Вывод в текстовый файл:");
double a = 12.234;
int b = 29;
f.WriteLine(" а = {0,6:С} b = {1,2:X}", a, b);
|
|
f.Close();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message); return;
}
}
}
}
В листинге 11.4 файл, созданный в предыдущем листинге, выводится на экран
Листинг 11.4. Чтение текстового файла
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
try
{
StreamReader f = new StreamReader("text.txt");
string s = f.ReadToEnd();
Console.WriteLine(s);
f.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.Message);
Console.WriteLine(" Проверьте правильность имени файла!");
return;
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return;
}
}
}
}
В этой программе весь файл считывается за один прием с помощью метода ReadToEnd. Чаще возникает необходимость считывать файл построчно, такой пример приведен в листинге 11.5. Каждая строка при выводе предваряется номером.
Листинг 11.5. Построчное чтение текстового файла
using System;
using System.IO;
namespace ConsoieApplication1
{
class Class1
{
static void Main() {
try
{
StreamReader f = new StreamReader("text.txt");
string s;
long i = 0;
while ((s = f.ReadLine())!= null)
Console.WriteLine("{0}: {1}", ++i, s);
f.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.Message);
Console.WnteLine("Проверьте правильность имени файла!");
return;
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return;
}
}
}
}
Пример преобразования чисел, содержащихся в текстовом файле, в их внутреннюю форму представления приведен в листинге 11.6. В программе вычисляется сумма чисел в каждой строке.
На содержимое файла накладываются весьма строгие ограничения: числа должны быть разделены ровно одним пробелом, после последнего числа в строке пробела быть не должно, файл не должен заканчиваться символом перевода строки. Методы разбиения строки и преобразования в целочисленное представление рассматривались ранее.
Листинг 11.6. Преобразования строк в числа
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
try
{
StreamReader f = new StreamReader("numbers.txt");
string s;
const int n = 20;
int[] a = new int[n];
string[] buf;
while ((s = f.ReadLine())!= null)
{
buf - s.Split(' ');
long sum = 0;
for (int i = 0; i < buf.Length; ++i)
{
a[i] = Convert.ToInt32(buf[i]);
sum += a[i];
}
Console.WriteLine("{0} сумма: {1}", s, sum);
}
f.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.Message);
Console.WriteLine(" Проверьте правильность имени файла!");
return;
}
catch (Exception e)
{
Console.WnteLine("Error: " + e.Message);
return;
}
}
}
}
Результат работы программы:
1 2 4 сумма: 7
3 44 -3 6 сумма: 50
8 1 1 сумма: 10