Опубликован: 11.09.2006 | Уровень: специалист | Доступ: платный
Лекция 2:

Работа с элементами управления

Чтение и запись файлов

При изучении синтаксиса языка С# вы сталкивались с чтением и записью файлов. Если при рассмотрении обработчиков OpenFileDialog и SaveFileDialog вы не до конца поняли, как .NET Framework работает с файлами, давайте еще раз разберемся с этим понятием.

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

  • считывать данные из потока;
  • записывать данные в поток;
  • производить поиск в потоке.

В С# все классы, которые представляют потоки, наследуются от абстрактного класса Stream. Класс Stream вместе со своими подклассами обеспечивает универсальное представление источников данных и архивов, абстрагированное от подробностей операционной системы. Классы потоков определены в пространстве имен System.IO.

Чтение и запись текстовых файлов

Для чтения и записи файлов, содержащих только текст, используются классы StreamReader и StreamWriter. Класс Stream Reader наследуется от класса TextReader, который считывает строки из стандартного текстового файла. Класс StreamWriter наследуется от класса TextWriter, записывающего символы в поток в специальном кодировании.

Создайте новое консольное приложение и назовите его FileStream. Скомпилируйте приложение (Ctrl+F5). В папке проекта создайте текстовый документ 1.txt. Откройте его в блокноте (или в приложении Notepad C#) и напишите в нем любой текст на русском и английском языках, сохранив затем его в кодировке Unicode. Выведем теперь записанный текст в окно консольного приложения. Переходим в код FileStream и подключаем пространство имен:

using System.IO;

В методе Main добавляем код:

[STAThread]
  static void Main(string[] args)
  {
//Cоздаем экземпляр Chitat  класса StreamReader и указываем путь к файлу 
и его название
    StreamReader Chitat = new StreamReader("1.txt");
    // Объявляем переменную A.
    string A;
    //В переменную А считываем содержимое файла
    A = Chitat.ReadToEnd();
    //Закрываем поток
    Chitat.Close();
    //Выводим переменную A в окно консольного приложения.
    Console.WriteLine(A);
  }

Когда вы работаете с файлом, например, редактируете документ Microsoft Word, вы не сможете удалить его или переместить — потому что приложение занято и поток открыт. Только завершив работу с документом и, следовательно, закрыв поток, можно перемещать его или открывать с помощью других приложений. Аналогично, в этом примере мы закрываем поток, вызывая метод Close, освобождая тем самым задействованные системные ресурсы.

Запускаем приложение. В консольном окне появляется текст, считанный из файла (рис. 2.32 ).

 Чтение текста из файла

Рис. 2.32. Чтение текста из файла

Добавим теперь объект класса StreamWriter, который будет записывать текст в файл:

[STAThread]
  static void Main(string[] args)
    {
      //Cоздаем экземпляр Chitat  класса StreamReader и указываем путь к файлу и его название
      StreamReader Chitat = new StreamReader("1.txt");
      // Объявляем переменную A.
      string A;
      //В переменную А считываем содержимое файла
      A = Chitat.ReadToEnd();
      //Закрываем поток
      Chitat.Close();
      //Выводим переменную A в окно консольного приложения.
      Console.WriteLine(A);
      //Cоздаем экземпляр Pisat  класса StreamWriter
      StreamWriter Pisat = new StreamWriter("1.txt", true, System.Text.Encoding.Unicode);
      //Вызываем метод Write экземпляра Pisat
      Pisat.Write("Добавляем текст");
      //Закрываем поток
      Pisat.Close();

      // Для того, чтобы не переходить в директорию 
      //для просмотра файла вручную, выведем его еще раз
      StreamReader ChitatSnova = new StreamReader("1.txt");
      string B;
      B = ChitatSnova.ReadToEnd();
      ChitatSnova.Close();
      Console.WriteLine(B);

    }
Листинг 2.14.

Метод Write добавил строку в файл (рис. 2.33):

Чтение и запись текста из файла

Рис. 2.33. Чтение и запись текста из файла

На диске, прилагаемом к книге, вы найдете приложение FileStream (Code\Glava2\ FileStream).

Object Browser и Intel Sense

В первой лекции мы рассматривали окно Object Browser. Использование этого окна зачастую может быть гораздо более удобным, чем поиск справочной информации в MSDN.

В предыдущем примере, при создании экземпляра Pisat класса StreamWriter следует указывать параметры, передаваемые классу, — при использовании Intel Sense всплывающая подсказка указывает, какие именно параметры следует передавать (рис. 2.34).

Группа из семи различных вариантов, предлагаемых Intel Sense. Для перемещения между вариантами щелкаем на кнопку со стрелкой — вариант 1 of 7

увеличить изображение
Рис. 2.34. Группа из семи различных вариантов, предлагаемых Intel Sense. Для перемещения между вариантами щелкаем на кнопку со стрелкой — вариант 1 of 7

Следуя подсказке, мы могли указать и передать такие параметры:

StreamWriter Pisat = new StreamWriter("1.txt");

В этом случае файл 1.txt перезаписывался и текстовая строка помещалась в пустой файл. Для добавления в файл нужно указывать булевскую переменную:

StreamWriter Pisat = new StreamWriter("1.txt", true);

В этом случае можно было бы добавлять в файл текст, содержащий только латинские буквы. Для корректной записи кириллицы следует указывать кодировку, например Unicode, что мы и сделали:

StreamWriter Pisat = new StreamWriter("1.txt", true, System.Text.Encoding.Unicode);

Возможны и другие варианты передаваемых параметров — например, указание размера передаваемого буфера в байтах.

Предположим, мы не знаем, какую именно кодировку следует указывать. В самом деле, Intel Sense на рис. 2 не указывает, что именно кодировка Unicode принадлежит пространству имен System.Text.Encoding. Но мы можем просмотреть все доступные объекты и свойства этого пространства, используя окно Object Browser (рис. 2.35).

 Пространство имен System.Text.Encoding в окне Object Browser

увеличить изображение
Рис. 2.35. Пространство имен System.Text.Encoding в окне Object Browser

В части окна Members отображаются и другие доступные кодировки, например, ASCII.

Проверка существования файла

При редактировании файла требуется определять его наличие на жестком диске для выбора потом варианта сохранения — целиком или только внесенных изменений. Создайте новое консольное приложение и назовите его FileExists. Следующий код демонстрирует проверку файла на диске:

using System.IO;
…

[STAThread]
    static void Main(string[] args)
    {
      //Выводим сообщение
      Console.WriteLine("Ведите название файла");
      // Создаем переменную nazvaniefayla, в которую
      //запишем название файла, введеное пользователем.
      string nazvaniefayla = Console.ReadLine();
      //Проверяем наличие файла (в директории bin/Debug)
      if (File.Exists(nazvaniefayla))
      {
        //Если файл существует, выводим его в консольное окно.
        StreamReader chitat = new StreamReader(nazvaniefayla);
        string A;
        A = chitat.ReadToEnd();
        chitat.Close();
        Console.WriteLine(A);
      }
      else 
      {
        //Если файл не найден, выводим окно сообщения
Сonsole.WriteLine("Файл с указанным именем не существует. Сoздать его Y/N");
        //Считываем результат пользователя
        string rezultatvibora = Console.ReadLine();
        if ((rezultatvibora=="Y")||(rezultatvibora=="y"))
        {
          //Создаем новый файл.
          StreamWriter pisat = new StreamWriter(nazvaniefayla);
          Console.WriteLine("Введите текст");
          string vvedemtext = Console.ReadLine();
          pisat.WriteLine(vvedemtext);
          pisat.Close();
          Console.WriteLine("Файл создан");
        }
        else 
        {
          // Если пользователь отказался от создания файла, выводим сообщение.
          Console.WriteLine("Ничего не будет созданно");
        }
      }
      


    }
Листинг 2.15.

На диске, прилагаемом к книге, вы найдете приложение FileExists (Code\Glava2\FileExists).

Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000