Практическое занятие № 5
Тема: Работа с файлами. Табулирование функций
Цель работы: получить практические навыки по обработке файлов и использованию компонентов для работы с файлами на языке С#
Ход работы
Задание 1. Работа стекстовыми файлами
Создайте форму, которая приведена на рисунке

Указания: Для формы задайте свойства: FormBorderStyle=FixedSingle, MaximizeBox = False, Text = Обработка файлов, StartPosition= CenterScreen.
Нанесите на форму 4 компонента Label для отображения надписей на Форме. Для четвертой надписи (на рисунке она красная) задайте свойства: Text - очистить, TextAlign = Center, ForeColor = красный.
Для отображения имен файлов нанесите на форму 2 поля TextBox и разместите их под 2 и 3 надписями.
Для отображения содержимого файлов нанесите на форму 3 компонента TextBox и задайте свойства: Text - очистить, MultiLine = True (поле становится многострочным), ReadOnly = True.
Добавьте на форму 2 кнопки Button. Для кнопок задайте свойство Text. Для 2 кнопки задайте свойство Enabled = False.
Кнопка "Загрузить файл" выводит диалог выбора текстового файла. После выбора содержимое файла загружается в левое текстовое поле.
Указания: нанесите на форму компонент OpenFileDialog и задайте свойство Filter = Текстовые файлы|*.txt
В коде опишем две глобальных переменные. Одна будет хранить имя исходного файла, вторая - имя каталога куда будут сохраняться созданные после обработки файлы.
Вверху кода формы после заголовка класса опишите переменные:
string file, path;
В событии Click кнопки введите код:
void button1_Click(object sender, EventArgs e)
{
//если файл не выбран, то подпрограмма завершает свою работу
if (openFileDialog1.ShowDialog()!=DialogResult.OK)
return;
//записываем в глобальную переменную имя выбранного файла
file = openFileDialog1.FileName;
//в левое многострочное поле загружаем содержимое выбранного файла
textBox3.Text = File.ReadAllText(file);
//в надписи вверху формы отображаем имя файла (без полного пути)
label4.Text = Path.GetFileName(file);
// разблокируем вторую кнопку
button2.Enabled = true;
}
В приведенном коде используются два класса:
File - для чтения данных из файла;
Path - для работы с путями .
Для использования этих классов надо подключить пространство имен:
using System.IO;
Кнопка "Обработать файл" позволяет обработать содержимое исходного текстового файла в соответствии с алгоритмом: положительные и нулевые элементы записываются в первый файл, отрицательные - во второй. Перед обработкой у пользователя с помощью диалога запрашивается имя каталога, куда будут сохранены полученные файлы.
Указания: для выбора пользователем нужного каталога нанесите на форму компонент FolderBrowserDialog.
Для 2 кнопки в событии Click напишем код:
void button2_Click(object sender, EventArgs e)
{
//если не заполнены полу 1 или поле 2 (имена новых файлов не указаны)
if (textBox1.Text == "" || textBox2.Text == "")
{
//выдаем сообщение об ошибке
MessageBox.Show("Недостаточно введенной информации.\nУкажите в полях имена файлов",
"Ошибка ввода",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
//ставим курсор в поле с именем первого файла
textBox1.Focus();
//подпрограмма завершает работу
return;
}
//описываем переменную для считывания данных из
исходного файла
string s;
//если в диалоге выбора имени каталога пользователь ничего не указал
//подпрограмма завершает работу
if (folderBrowserDialog1.ShowDialog()!=DialogResult.OK)
return;
//в глобальную переменную записываем заданный пользователем каталог
path = folderBrowserDialog1.SelectedPath;
//переменная sr связывается с исходным файлов для чтения
StreamReader sr = new StreamReader(file);
//переменная sw1 связывается с первым результирующим файлом для записи
//файл записывается в каталог, имя которого находится в переменной path,
//а имя находится в поле textBox1
StreamWriter sw1 = new StreamWriter(path+"\\"+textBox1.Text,false);
//переменная sw2 связывается со вторым результирующим файлом для записи
//файл записывается в каталог, имя которого находится в переменной path,
//а имя находится в поле textBox2
StreamWriter sw2 = new StreamWriter(path+"\\"+textBox2.Text,false);
//цикл до конца исходного файла
//сменная sr связана с исходным файлом
while (!sr.EndOfStream)
{
//в переменную считываем строку исходного файла
s=sr.ReadLine();
//прочитанная информация конвертируется в число
//если это число положительное
if (Convert.ToDouble(s)>=0)
//оно записывается в первый результирующий файл
sw1.WriteLine(s);
//иначе, если число отрицательное
else
//оно записывается во второй результирующий файл
sw2.WriteLine(s);
}
//закрываем все файлы
sr.Close();
sw1.Close();
sw2.Close();
//загружаем полученные файлы во 2 и 3 многострочные поля
textBox4.Text = File.ReadAllText(path+"\\"+textBox1.Text);
textBox5.Text = File.ReadAllText(path+"\\"+textBox2.Text);
}
Задание 2. Табулирование функции
Создайте форму, которая приведена на рисунке

Указания: Для формы задайте свойства: FormBorderStyle=FixedSingle, MaximizeBox = False, Text = Работа с файлами, StartPosition= CenterScreen.
Для создания счетчиков нанесите на форму 3 компонента NumericUpDown и задайте свойства: Min = 0, Max = 100, Increment = 0,1 (шаг), DecimalPlaces = 1 (количество знаков после запятой в счетчике).
Кнопка "Рассчитать" выводит в текстовое поле таблицу значений функции y=sin4x на отрезке [a,b] с заданным шагом. При этом проверяются ситуации, чтобы начало отрезка не превышало конец отрезка, чтобы шаг не был меньшим или равным 0.
При выдачи таблицы значений функции нужно выдать заголовок, шапку таблицы, а потом значения.
При выоде таблицы может возникать ситуация, когда в поле Memo может находиться текст с результатами предыдущего расчетов. В этом случае нужно выдавать запрос на перезапись значений или добавление новых значений в конец поля.
Указания: Нанесите на форму компонент TextBox и задайте свойства: MultiLine = True (поле станет многострочным), Text - очистить, TextAlign = Center, Font=CourierNew, ReadOnly=True, ScrollBars = None (скрыть полосы прокрутки).
Растяните поле так, чтобы в нем по вертикали помещалось 17 строк текста.
Напишем код, который будет отображать в поле вертикальную полосу прокрутки, если количество строк превышает 17.
В событии TextChanged поля введите код:
void textBox1_TextChanged(object sender, EventArgs e)
{
//если количество строк превышает 17
if (textBox1.Lines.Length>17)
//в поле отображаем вертикальную полосу прокрутки
textBox1.ScrollBars= ScrollBars.Vertical;
//в другом случае полоса прокрутки исчезает
else
textBox1.ScrollBars=Scrollbars.None;
}
Нанесите на форму 4 кнопки Button и задайте им свойство Text. При старте 2, 3 и 4 кнопки должны быть заблокированы. Задайте для них свойство Enabled = False.
Для расчетов будем записывать содержимое счетчиков в переменные. Эти же переменные нам понадобятся для выполнения экспорта данных (третья кнопка). Поэтому опишем их как глобальные. Вверху кода формы сразу после заголовка класса формы опишите нужны переменные:
double a,b,h;
Для выполнения расчетов в событии Click кнопки напишем код:
void button1_Click(object sender, EventArgs e)
{
//записываем значение счетчиков в переменные
a = Convert.ToDouble(numericUpDown1.Value);
b = Convert.ToDouble(numericUpDown2.Value);
h = Convert.ToDouble(numericUpDown3.Value);
//если начало отрезка превышает конец отрезка
if (a>b)
{
//выдаем сообщение об ошибке
MessageBox.Show("Начало отрезка не может превышать конец",
"Ошибка ввода данных",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
//ставим курсор в первый счетчик
numericUpDown1.Focus();
//завершаем работу процедуры
return;
}
//если шаг меньше или равен нулю
if (h<=0)
{
//выдаем сообщение об ошибке
MessageBox.Show("Шаг должен быть больше 0",
"Ошибка ввода данных",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
//ставим курсор в третий счетчик
numericUpDown3.Focus();
//завершаем работу процедуры
return;
}
//если начинается расчеты, а в поле уже есть информация
if (textBox1.Text!="")
//выдаем запрос на очистку содержимого поля
if (MessageBox.Show("Очистить поле результата?",
"Подтвердите",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)==DialogResult.Yes)
//если пользователь подтвердил операцию, поле очищается
textBox1.Clear();
//добавляем в поле шапку таблицы
//константа Environment.NewLine переводит курсор на новую строку
textBox1.AppendText("Табулирование функции"+Environment.NewLine);
textBox1.AppendText("====================="+Environment.NewLine);
textBox1.AppendText(" X | Y "+Environment.NewLine);
textBox1.AppendText("====================="+Environment.NewLine);
//переменную a запишем в буферную переменную, чтобы не потерять ее значения
double i;
i=a;
//запускаем цикл от i до b с шагом h
while (i<=b)
{
//для каждого значения аргумента рассчитываем значение функции
//с помощью метода String.Format() форматируем значение
//и добавляем его в поле как строку таблицы
textBox1.AppendText(String.Format(" {0,4:f1} | {1,6:f3} ",
i, Math.Sin(4*i)) + Environment.NewLine);
//наращиваем значение аргумент на заданный шаг
i+=h;
}
//после формирования таблицы подчеркиваем ее линией
textBox1.AppendText("====================="+Environment.NewLine);
//ставим отметку, что значение поля не сохранено на диске
textBox1.Modified=true;
//разблокируем все кнопки на форме для работы
button2.Enabled=button3.Enabled=button4.Enabled=true;
}
Кнопка "Сохранить" позволяет сохранить в указанный файл содержимое поля. При этом появляется окно диалога сохранения файла. Если указанный при сохранении файл уже существует на диске, то нужно выдать запрос на перезапись файла или добавление в него новой информации.
Указания: Для сохранения содержимого поля в текстовый файл на форму нанесите компонент SaveFileDialog
Для 2 кнопки в событии Click напишем код:
void button2_Click(object sender, EventArgs e)
{
//задаем маску для файлов
saveFileDialog1.Filter="Текстовые файлы|*.txt";
//задаем расширение для файлов
saveFileDialog1.DefaultExt="txt";
//очищаем старое имя файла
saveFileDialog1.FileName="";
//отключаем запрос на перезапись существующего файла
//мы будем выдавать свой запрос
saveFileDialog1.OverwritePrompt = false;
//если в диалоге сохранения пользователь не указал файл
//подпрограмма завершает свою работу
if (saveFileDialog1.ShowDialog()!=DialogResult.OK)
return;
//если указанный файл существует
if (File.Exists(saveFileDialog1.FileName))
//выдаем запрос на его дописывание
if (MessageBox.Show("Дописать данные в файл?",
"Подтвердите",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)==DialogResult.Yes)
//если пользователь согласился дописать файл
//в указанный файл добавляется содержимое поля формы
File.AppendAllLines(saveFileDialog1.FileName,textBox1.Lines);
//если пользователь не согласился на дописывание
else
//указанный файл перезаписывается содержимым поля формы
File.WriteAllLines(saveFileDialog1.FileName,textBox1.Lines);
//если указанный файл не существует на диске
else
//в указанный файл записывается содержимое поля на форме
File.WriteAllLines(saveFileDialog1.FileName,textBox1.Lines);
// у поля снимается отметка о том, что содержимое поля не сохранено на диск
// то есть данные были сохраненные
textBox1.Modified=false;
}
Обратите внимание что в коде используется класс File, для работы с которым надо подключить пространство имен
using System.IO;
Кнопка "Экспорт" позволяет сохранить в указанный файл содержимое поля. При этом содержимое поля построчноо форматируется в HTML и записывается в файл. Имя файла указывается с помощью диалога сохранения файла.
Указания: Для сохранения содержимого поля в HTML файл для 3 кнопки напишем код:
void button3_Click(object sender, EventArgs e)
{
//задаем маску для файлов
saveFileDialog1.Filter="Файлы HTML|*.html";
//задаем расширение для файлов
saveFileDialog1.DefaultExt="html";
//очищаем старое имя файла
saveFileDialog1.FileName="";
//включаем запрос на перезапись существующего файла
saveFileDialog1.OverwritePrompt = true;
//если в диалоге сохранения пользователь не выбрал файл
//подпрограмма завершает свою работу
if (saveFileDialog1.ShowDialog()!=DialogResult.OK)
return;
//так как будем формировать содержимое файла построчно,
//опишем переменную типа StreanWriter, которая предназначена для этих целей
//переменная связывается с файлом, который задан в диалоге
//параметр false указывает, что файл надо перезаписать
//(если указать true), то файл дописывается
StreamWriter sw = new StreamWriter(saveFileDialog1.FileName,false);
//записываем в файл заголовок и шапку таблицы
//с использованием HTML тегов
sw.WriteLine("<head>");
sw.WriteLine("<title>Табулирование функции</title>");
sw.WriteLine("<meta charset=utf-8>");
sw.WriteLine("</head>");
sw.WriteLine("<body>");
sw.WriteLine("<h2 align=center>Табулирование функции</h2>");
sw.WriteLine("<table border=1 width=30% align=center>");
sw.WriteLine("<th width=50%>X</td>");
sw.WriteLine("<th>Y</th>");
//в цикле записываем в файл построчно значения аргумента и функции
while (a<=b)
{
sw.WriteLine("<tr>");
sw.WriteLine("<td align=center>"+Math.Round(a,1).ToString()+"</td>");
sw.WriteLine("<td align=center>"+Math.Round(Math.Sin(4*a),3).Tostring()+"</td>");
sw.WriteLine("</tr>");
//наращиваем аргумент на шаг
a+=h;
}
//закрываем тег таблицы и HTML документа
sw.Writeline("</table>");
sw.WriteLine("</body>");
//закрываем файл
sw.Close();
}
Кнопка "Очистить" очищает поле.
Указания: Для очистки поля для 4 кнопки напишем код:
void button4_Click(object sender, EventArgs e)
{
//выдаем запрос на очистку полей
if (MessageBox.Show("Очистить поле результата?",
"Подтвердите",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)==DialogResult.Yes)
{
//если пользователь подтвердил операцию, то поле очищается
textBox1.Clear();
//кнопки 2, 3, 4 блокируются
button2.Enabled=button3.Enabled=button4.Enabled=false;
//курсор ставится в первый счетчик
numericUpDown1.Focus();
//у поля снимается отметка о том, что содержимое поля не сохранено
//сохранять ничего
textBox1.Modified=false;
}
}
Если пользователь рассчитает таблицу значений функции и без сохранения результата попробует выйти из программы, то нужно выдать сообщение о необходимости сохранения данных и обработать ответ пользователя.
Указания: Для формы в событии FormClosing напишем код:
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//если у поля включена метка о том, что содержимое поля не сохранено
if (textBox1.Modified)
//выдаем запрос на сохранение содержимого поля
if (MessageBox.Show("Данные не сохранены. Сохранить?",
"Подтвердите",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question)==DialogResult.Yes)
//если пользователь подтвердил сохранение данных
//выполняем процедуру для кнопки "Сохранить"
button2_Click(sender, e);
}