Чтение и запись текстовых файлов в C#. StreamWriter и StreamReader

Для работы с текстовыми файлами в C# предназначены классы StreamReader (для чтения) и StreamWriter (для записи). В отличие от класса FileStream, который оперирует данными на уровне байтов, эти классы работают со строками и символами и, соответственно, имеют специализированные методы для выполнения операций чтения/записи текстовых данных.

Запись текстовых файлов в C# (класс StreamWriter)

Для записи текстовых файлов используется класс StreamWriter, который содержит ряд конструкторов. Рассмотрим наиболее часто используемые конструкторы StreamWriter.

Первый конструктор принимает в качестве параметра ранее созданный поток (например, FileStream или MemoryStream) и использует кодировку по умолчанию — UTF-8:

string fileName = @"c:\CSharp Output\TextFile.txt";
using FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
{
     using StreamWriter writer = new StreamWriter(fs)
     {
        //работаем с экземпляром StreamWriter
     };
}

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

string fileName = @"c:\CSharp Output\TextFile.txt";
using StreamWriter writer = new StreamWriter(fileName, false, Encoding.ASCII);

второй параметр конструктора указывает на то будет ли добавляться в файл текст (true), если файл существует или же файл будет полностью перезаписан (false). Кроме этих двух, также имеются конструкторы, которые позволяют указывать дополнительные параметры для потока, содержащего файл, например, настройки совместного доступа, режима доступа и т.д.

После того, как объект класс StreamWriter создан, можно записывать данные в файл. Для этого, у класса определены следующие методы:

Метод Асинхронная версия

Описание

Flush() FlushAsync()

Очищает все буферы для текущего средства записи и вызывает запись всех данных буфера в основной поток.

Write() WriteAsync()

Записывает текстовое представление различных типов данных (char, int, double, string и т.д.) в текстовый поток. Асинхронная версия метода доступна не для всех поддерживаемых типов данных. Например, отсутствует асинхронный метод для записи чисел в текстовый поток.

WriteLine() WriteLineAsync()

Записывает текстовое представление различных типов данных (char, int, double, string и т.д.) в текстовый поток, за которым следует знак конца строки. Асинхронная версия метода доступна не для всех поддерживаемых типов данных. Например, отсутствует асинхронный метод для записи чисел в текстовый поток.

 

Ниже представлен пример записи различных данных в текстовый файл:

string fileName = @"c:\CSharp Output\TextFile.txt";
using StreamWriter writer = new StreamWriter(fileName, false, Encoding.ASCII);
writer.WriteLine("Hello world!");//записываем строку
writer.WriteLine(123);//записываем целое число
writer.WriteLine(true);//записываем bool
byte[] buffer = Encoding.ASCII.GetBytes("StreamWriter");
writer.WriteLine(Encoding.ASCII.GetChars(buffer));//записываем массив символов

В результате будет создан файл со следующим содержимым:

Hello world!
123
True
StreamWriter

Следует отметить, что, в случае, если мы создаем экземпляр StreamWriter с использованием ранее открытого потока, то позиция курсора в потоке не сбрасывается. Продемонстрировать это можно на следующем примере:

string fileName = @"c:\CSharp Output\TextFile.txt";
using FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
fs.Write(Encoding.ASCII.GetBytes("Hello, StreamWriter"));
fs.Seek(7, SeekOrigin.Begin);//смещаемся на 7 байт от начала потока.

//создаем экземпляр StreamWriter
using StreamWriter writer = new StreamWriter(fs, Encoding.ASCII);
writer.Write("FileStream  ");

Здесь мы создали файловый поток FileStream и записали в него строку «Hello, StreamWriter» после чего смесились на семь байт вправо от начала файла (о том, как работает смещение — см. здесь). Далее, так как позиция курсора в потоке сохраняется, то запись строки «FileStream » с использованием StreamWriter в данном случае переписывает часть строки и, в итоге, в файле мы увидим текст:

Hello, FileStream

Если вам необходимо сбросить позицию курсора в потоке, то можно воспользоваться свойством BaseStream у StreamWriter:

using StreamWriter writer = new StreamWriter(fs, Encoding.ASCII);
writer.BaseStream.Position = 0;

Чтение текстовых файлов в C# (класс StreamReader)

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

Метод Асинхронная версия

Описание

Peek()  

Возвращает следующий доступный символ, но не использует его.

Read()  

Выполняет чтение следующего символа из входного потока и перемещает положение символа на одну позицию вперед.

Read(Char[], Int32, Int32) ReadAsync(Char[], Int32, Int32)

Считывает заданное максимальное количество символов из текущего потока в буфер начиная с заданного индекса.

ReadLine() ReadLineAsync()

Выполняет чтение строки символов из текущего потока и возвращает данные в виде строки.

ReadToEnd() ReadToEndAsync()

Считывает все символы, начиная с текущей позиции до конца потока.

Здесь стоит обратить внимание на метод Peek(). Метод Peek() возвращает очередной символ или -1, если достигнут конец файла, но, при этом не изменяет положение курсора в потоке. В связи с этим, метод Peek() может использоваться, например, для посимвольного чтения файла:

using StreamReader reader = new StreamReader(fileName, Encoding.ASCII);
reader.BaseStream.Position = 0;
while (true)
{
    if (reader.Peek()<0)
       break;
    Console.WriteLine((char)reader.Read());
}

Методы ReadLine и ReadLineAsync удобно использовать для построчного чтения файла. Если достигнут конец файла, то метод вернет значение null. Например, так можно открыть текстовый файл в C# и прочитать его по-строчно:

using StreamReader reader = new StreamReader(fileName, Encoding.ASCII);
reader.BaseStream.Position = 0;
while (true)
{
    var str = await reader.ReadLineAsync();
    if (str == null) //достигнут конец файла
        break;
    Console.WriteLine(str);
}

Итого

Для работы с текстовыми файлами в C# используются специализированные классы — StreamWriter и StreamReader, содержащие методы для работы именно с символами и строками, что позволяет без дополнительных преобразований, например, записывать в файл текстовое представление чисел и других типов данных. 

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии