C#. Классы StreamReader и StreamWriter. Работа с текстовыми файлами




Классы StreamReader и StreamWriter. Работа с текстовыми файлами. Конструкторы класса StreamReader


Содержание


Поиск на других ресурсах:

1. Классы StreamReader, StreamWriter. Назначение

Классы StreamReader и StreamWriter используются для работы с потоками символьных данных. Наибольшее применение классов — работа с текстовыми файлами.

Класс StreamReader используется для чтения из потока символьных данных. Класс StreamReader является производным от абстрактного класса TextReader (рисунок 1), который объявляет базовые методы для считывания символов из байтового потока в заданной системе кодирования. В свою очередь, класс StreamReader реализует методы класса TextReader и является основным классом, который применяется для чтения информации из текстовых файлов.

C#. Иерархия классов TextReader и StreamReader

Рисунок 1. Классы TextReader и StreamReader

Класс StreamWriter используется для записи в поток символов в заданной кодировке. Класс является производным от абстрактного класса TextWriter (рисунок 2) и реализует его методы. Класс StreamWriter является основным классом, который используется для записи символьных данных в файл.

C#. Классы TextWriter и StreamWriter

Рисунок 2. Классы TextWriter и StreamWriter

Для того, чтобы использовать классы StreamReader и StreamWriter, в программе нужно подключить пространство имен System.IO

// Подключить пространство имен System.IO
using System.IO;

 

2. Обзор методов и свойств класса StreamReader

Далее приведен перечень основных методов, которые унаследованы от класса TextReader и реализованы в классе StreamReader:

  • Close() — закрывает объект типа StreamReader и базовый поток и освобождает все системные ресурсы, связанные с этим объектом;
  • Dispose() — закрывает базовый поток и дает возможность задать освобождение управляемых ресурсов;
  • Peek() — возвращает следующий доступный символ без смещения позиции указателя чтения из файла;
  • Read() — читает один или несколько символов (в зависимости от реализации) со смещением указателя чтения из файла;
  • ReadAsync() — читает асинхронно заданное количество символов из потока и записывает данные в буфер;
  • ReadBlock() — читает массив символов в заданный буфер;
  • ReadBlockAsync() — читает массив символов из текущего потока асинхронно;
  • ReadLine() — читает строку символов из потока до символа новой строки;
  • ReadLineAsync() — читает асинхронно строку символов;
  • ReadToEnd() — считывает все символы из потока, начиная с текущей позиции до конца потока;
  • ReadToEnd() — считывает асинхронно все символы из потока, начиная с текущей позиции указателя чтения до конца потока.

В классе StreamReader есть 3 свойства, не унаследованные от класса TextReader:

  • BaseStream — возвращает основной поток;
  • CurrentEncoding — возвращает текущую кодировку потока;
  • EndOfStream — определяет, не достигнут ли конец потока.

 

3. Конструкторы класса StreamReader. Создание потока, связанного с текстовым файлом

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

try
{
  // Создать поток ввода путем вызова конструктора
  StreamReader fIn = StreamReader(...);

  // Использовать поток ввода
  ...

  // Закрыть поток ввода
  fIn.Close();
}
catch (ExceptionType1 e)
{
  // Обработать исключение ExceptionType1
  ...
}
catch (ExceptionType1 e)
{
  // Обработать исключение ExceptionType2
  ...
}
...
catch (ExceptionTypeN e)
{
  // Обработать исключение ExceptionTypeN
  ...
}

В вышеприведенном фрагменте ExceptionType1, ExceptionType2 …, ExceptionTypeN — типы исключений, которые могут возникать при использовании одного из конструкторов класса StreamReader.

 

3.1. Конструктор StreamReader(string)

Данный конструктор инициализирует новый экземпляр класса StreamReader для определенного имени файла. Общая форма конструктора

public StreamReader(string path);

здесь

  • path – путь к файлу.

При использовании конструктора могут быть сгенерированы исключения следующих типов:

  • System.ArgumentException — путь path является пустой строкой «»;
  • System.ArgumentNullException — путь path равен null;
  • System.IO.FileNotFoundException — файл не найден;
  • System.IO.DirectoryNotFoundException — путь указан неправильно;
  • System.IO.IOException — путь включает некорректный или ложный синтаксис для имени файла, имени директория или метки тома.

Пример.

using System;

// Подключить пространство имен System.IO
using System.IO;

namespace ConsoleApp12
{
  class Program
  {
    static void Main(string[] args)
    {
      // Создать экземпляр потока
      // с помощью конструктора StreamReader(string)
      try
      {
        StreamReader fInput = new StreamReader("myfile1.txt");

        // Использовать поток
        // ...

        // Закрыть поток
        fInput.Close();
      }
      catch (ArgumentException e)
      {
        Console.WriteLine(e.Message);
      }
      catch (FileNotFoundException e)
      {
        Console.WriteLine(e.Message);
      }
      catch (DirectoryNotFoundException e)
      {
        Console.WriteLine(e.Message);
      }
      catch (IOException e)
      {
        Console.WriteLine(e.Message);
      }
    }
  }
}

Цепочку блоков catch() можно объединить в один блок, который обрабатывает тип исключения Exception по следующему образцу

...

// Создать экземпляр потока
// с помощью конструктора StreamReader(string)
try
{
  StreamReader fInput = new StreamReader("myfile1.txt");

  // Использовать поток
  // ...

  // Закрыть поток
  fInput.Close();
}
catch (System.Exception e)
{
  Console.WriteLine(e.Message);
}

...

 

3.2. Конструктор StreamReader(string, System.Text.Encoding)

При чтении потока ввода существует возможность указать кодировку символов. Для этого используется конструктор

public StreamReader(string path, System.Text.Encoding encoding);

Возможны исключения следующих типов:

  • System.ArgumentException — путь path является пустой строкой «»;
  • System.ArgumentNullException — путь path равен null;
  • System.IO.FileNotFoundException — файл не найден;
  • System.IO.DirectoryNotFoundException — путь задан неправильно;
  • System.NotSupportedException — путь path включает некорректный или ложный синтаксис имени файла, имени директория или метки тома.

Пример.

using System;

// Подключить пространство имен System.IO
using System.IO;

...

// Создать экземпляр потока
try
{
  // Создать ASCII-кодировку символов
  System.Text.Encoding encoding = System.Text.Encoding.ASCII;

  // Открыть поток ввода в указанной кодировке
  StreamReader fInput = new StreamReader("myfile1.txt", encoding);

  // Использовать поток
  // ...

  // Закрыть поток
  fInput.Close();
}
catch (System.Exception e)
{
  Console.WriteLine(e.Message);
}

...

 

3.3. Конструктор StreamReader(System.IO.Stream)

С помощью данного конструктора существует возможность создать поток ввода из другого потока, унаследованного от базового класса Stream (например, из потока FileStream). Общая форма такого конструктора следующая

public StreamReader(System.IO.Stream stream);

здесь stream – определенный поток, связанный с файлом.

При использовании конструктора возможны следующие исключительные ситуации:

  • System.ArgumentException — поток не поддерживает чтение;
  • System.ArgumentNullException — поток или кодировка равны null.

Пример.

using System;
using System.IO;

...

// Использовать оператор using()
// 1. Создать экземпляр потока FileStream
using (FileStream inputStream = new FileStream("myfile1.txt", FileMode.Open))
{
  // 2. Создать экземпляр потока StreamReader()
  // с помощью конструктора StreamReader(Stream)
  using (StreamReader fInput = new StreamReader(inputStream))
  {
    // Использовать поток fInput
    // ...
  }
}

...

 

3.4. Конструктор StreamReader(System.IO.Stream, System.Text.Encoding)

Данный конструктор создает поток ввода из другого потока ввода на основании указнной кодировки символов. Согласно документации объявление конструктора следующее

public StreamReader(System.IO.Stream stream, System.Text.Encoding encoding)

здесь

  • stream – поток, который должен быть прочитан;
  • encoding – система кодировки (Unicode, UTF-8, UTF 7 и т.д.).

При использовании конструктора могут возникнуть исключительные ситуации следующих типов:

  • System.ArgumentException — путь path является пустой строкой «»;
  • System.ArgumentNullException — путь path равен null.

Пример.

using System;

// Подключить пространство имен System.IO
using System.IO;

...

try
{
  // 1. Создать экземпляр потока FileStream
  FileStream inputStream = new FileStream("myfile1.txt", FileMode.Open);

  // 2. Создать экземпляр потока StreamReader()
  // с помощью конструктора StreamReader(Stream, System.Text.Encoding)
  // в системе кодировки UTF-8
  StreamReader fInput = new StreamReader(inputStream, System.Text.Encoding.UTF8);

  // Использовать поток
  // ...

  // Закрыть поток
  fInput.Close();
}
catch (System.Exception e)
{
  Console.WriteLine(e.Message);
}

...

 

4. Использование оператора using() при создании потока ввода

Создание потока ввода типа StreamReader осуществляется с использованием одного из доступных конструкторов. Каждый конструктор имеет свои особенности и содержит разное количество параметров. После работы с потоком ввода этот поток нужно закрыть методом Close().

// Подключить пространство имен System.IO
using System.IO;

...

StreamReader fIn = StreamReader(...);

// Обработка потока fIn
...

// Закрыть поток fIn
fIn.Close();

...

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

using (StreamReader fIn=StreamReader(...))
{
  // Обработка потока fIn
  ...
}

Пример. В примере с помощью оператора using() создается поток типа FileStream из файла myfile1.txt. Вызывается конструктор класса FileStream. Затем с помощью вложенного оператора using() создается поток ввода типа StreamReader. После использования, потоки не нужно закрывать методом Close(), поскольку ресурсы, связанные с этими потоками будут освобождены (закрыты) автоматически.

...

// Создать экземпляр потока FileStream
using (FileStream fs = new FileStream("myfile1.txt", FileMode.Open))
{
  // Создать экземпляр StreamReader
  using (StreamReader fIn = new StreamReader(fs))
  {

    // Использование потока StreamReader
    // ...

  }
}

...

 


Связанные темы