Содержание
Для работы с текстовыми файлами в 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() |
Flush |
Очищает все буферы для текущего средства записи и вызывает запись всех данных буфера в основной поток. |
Write() |
Write |
Записывает текстовое представление различных типов данных ( |
Write |
Write |
Записывает текстовое представление различных типов данных ( |
Ниже представлен пример записи различных данных в текстовый файл:
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));//записываем массив символов
В результате будет создан файл со следующим содержимым:
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
в данном случае переписывает часть строки и, в итоге, в файле мы увидим текст:
Если вам необходимо сбросить позицию курсора в потоке, то можно воспользоваться свойством BaseStream
у StreamWriter
:
using StreamWriter writer = new StreamWriter(fs, Encoding.ASCII); writer.BaseStream.Position = 0;
Чтение текстовых файлов в C# (класс StreamReader)
Для чтения текстовых файлов используется класс StreamReader
. У этого класса определены конструкторы, аналогичные конструкторам класса StreaWriter
, поэтому перечислять их не будем, а сразу перейдем к рассмотрению методов класса, основные из которых перечислены в таблице ниже:
Метод | Асинхронная версия |
Описание |
---|---|---|
Peek() |
Возвращает следующий доступный символ, но не использует его. |
|
Read() |
Выполняет чтение следующего символа из входного потока и перемещает положение символа на одну позицию вперед. |
|
Read(Char[], Int32, Int32) |
Read |
Считывает заданное максимальное количество символов из текущего потока в буфер начиная с заданного индекса. |
Read |
Read |
Выполняет чтение строки символов из текущего потока и возвращает данные в виде строки. |
Read |
Read |
Считывает все символы, начиная с текущей позиции до конца потока. |
Здесь стоит обратить внимание на метод 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
, содержащие методы для работы именно с символами и строками, что позволяет без дополнительных преобразований, например, записывать в файл текстовое представление чисел и других типов данных.