Шаг 295.
Язык программирования C#. Начала.
Немного о разном. Работа с файлами (и еще продолжение)

    На этом шаге мы рассмотрим создание и использование символьных потоков.

    Еще раз подчеркнем, что особенность байтового потока в том, что данные считываются блоками размером в байт. На практике нередко приходится иметь дело с символьными данными. Символ реализуется в виде блока размером в два байта. Поэтому при работе с символьной информацией удобнее выполнять ввод и вывод данных блоками размером по два байта - то есть посимвольно. В таком случае используют символьные потоки. Объекты символьных потоков создаются на основе классов StreamReader (поток для считывания) и StreamWriter (поток для записи). Но в основе символьного потока все равно лежит байтовый поток. Разница лишь в том, какими блоками считывается и записывается информация. Это отражается и на процессе создания символьных потоков: аргументом конструктору класса, на основе которого создается символьный поток, передается объект байтового потока. Вместе с тем существует и другой способ создать символьный поток: аргументом конструктору класса StreamReader или StreamWriter достаточно передать текст с именем файла, на основе которого создается поток.

    Объект символьного потока для считывания данных создается на основе класса StreamReader. Для считывания одного символа используется метод Read(). Результатом метода возвращается int-значение с кодом символа или значение -1, если достигнут конец файла. Метод ReadLine() позволяет считать текстовую строку. Текстовая строка возвращается результатом метода. Если достигнут конец файла, то метод возвращает пустую ссылку null.

    Объект символьного потока для записи данных в файл создается на основе класса SreamWriter. Для записи данных в файл используются методы Write() и WriteLine(). Разница между методами в том, что метод WriteLine() после занесения данных в файл добавляет инструкцию перехода к новой строке. Пример создания и использования символьных потоков представлен в нижеследующем примере.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace pr295_1
{
    // Главный класс:
    class Program
    {
        // Главный метод: 
        static void Main()
        {
            // Название и полный путь для файла: 
            string file = "MyText.txt";
            // Текстовая переменная: 
            string str;
            // Ключевое слово: 
            string word = "exit";
            // Целочисленная переменная: 
            int k = 1;
            try
            { // Контролируемый код
                // Символьный поток для записи в файл:
                StreamWriter fw = new StreamWriter(file);
                Console.WriteLine("Для завершения введите \"{0}\"", word);
                // Считывание текстовых строк с консоли: 
                do
                {
                    // Приглашение ввести строку:
                    Console.Write("{0}-я строка: > ", k);
                    k++;
                    // Считывание текстовой строки с консоли: 
                    str = Console.ReadLine();
                    if (str == word)
                    { // Если введено ключевое слово 
                        // Завершение оператора: 
                        break;
                    }
                    else
                    { // Если не введено ключевое слово 
                        // Запись текстовой строки в файл: 
                        fw.WriteLine(str);
                    }
                } while (true);
                // Закрывается поток: 
                fw.Close();
                Console.WriteLine("Файл создан!");
                // Создание потока для считывания из файла:
                StreamReader fr = new StreamReader(file);
                Console.WriteLine("Содержимое файла:");
                // Считывание строки из файла: 
                str = fr.ReadLine();
                // Построчное считывание содержимого файла: 
                while (str != null)
                {
                    // Отображение считанной из файла строки:
                    Console.WriteLine(str);
                    // Считывание строки из файла: 
                    str = fr.ReadLine();
                }
                // Закрывается поток: 
                fr.Close();
            }
            // Обработка исключений: 
            catch (Exception e)
            {
                Console.WriteLine("Произошла ошибка!");
                Console.WriteLine(e.Message);
            }
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Программа выполняется следующим образом: пользователь последовательно вводит текстовые строки, которые считываются и построчно записываются в текстовый файл. Файл создается программой. Процесс ввода строк завершается, когда пользователь вводит ключевое слово "exit". После этого содержимое созданного файла построчно считывается и построчно отображается в консольном окне.

    В программе в текстовую переменную file записывается полный путь к текстовому файлу, который создается программой, а также название файла. Текстовая переменная str используется для запоминания текстовых строк, которые будет вводить пользователь. В текстовую переменную word записывается ключевое слово, ввод которого означает завершение процесса формирования содержимого текстового файла. Целочисленная переменная k используется для нумерации строк.

    Объект fw символьного потока для записи данных в файл создается командой

  StreamWriter fw = new StreamWriter(file);               . 
Затем запускается формально бесконечный цикл конструкцией do-while (в нем проверяемым условием указано значение true). В теле цикла командой
  str = Console.ReadLine();
считывается строка, введенная пользователем. Далее в условной конструкции проверяется условие str==word. Условие истинно, если пользователь ввел ключевое слово. Если так, то командой break завершается выполнение цикла. В противном случае (если условие ложно) командой
  fw.WriteLine(str); 
текстовая строка записывается в файл.

    По завершении выполнения цикла командой

  fw.Close(); 
закрывается символьный поток. После этого командой
  StreamReader fr = new StreamReader(file);
создается объект символьного потока для считывания данных из файла, который был создан и заполнен на предыдущем этапе. Командой
  str = fr.ReadLine(); 
из файла считывается первая строка (если она есть), после чего запускается цикл while. В конструкции цикла проверяется условие str!=null. Истинность условия означает, что конец файла не достигнут и переменная str содержит ссылку на текст. В этом случае командой
  Console.WriteLine(str);
считанная из файла строка отображается в консольном окне. Затем командой
  str = fr.ReadLine(); 
из файла считывается следующая строка. После того как содержимое файла прочитано, командой
  fr.Close(); 

    Результат выполнения программы может быть таким:


Рис.1. Результат выполнения приложения

    Также стоит отметить, что в результате выполнения программы в каталоге bin\Debug приложения создается файл с названием MyText.txt. Содержимое этого файла показано на рисунке 2.


Рис.2. Содержимое текстового файла, созданного в результате выполнения программы

    Несложно догадаться, что именно это содержимое отображалось в консольном окне.

    На следующем шаге мы рассмотрим работу с бинарными файлами.




Предыдущий шаг Содержание Следующий шаг