Файлы данных (Пространство имен System.IO). Файлы и потоки
Файл данных — это совокупность (последовательность) компонент, имеющая имя, расположенная на внешнем носителе. Файлы могут быть объединены в каталоги (директории, папки), также имеющие имя. Использование файлов данных позволяет хранить данные на внешнем носителе, обрабатывая при необходимости порциями (например, при больших объемах данных), позволяет многократно использовать один и тот же набор данных (например, при отладке), позволяет использовать результаты выполнения одной программы (формируя из них файл) как входные данные при выполнении другой программы и т.п.
Для существующего файла данных, который храниться на внешнем носителе и имеет имя, при обращении к файлу создается поток с целью сохранения данных в резервном хранилище. Резервное хранилище — это устройство хранения информации, например, диск или память.
Поток — это абстракция последовательности байтов, например файл или другое устройство, предоставляющее данные. Класс Stream (поток) и его производные классы предоставляют универсальное представление различных типов ввода и вывода, избавляя программиста от необходимости знания отдельных сведений операционной системы и базовых устройств.
Потоки включают три основные операции:
1. Чтение из потока — это перенос информации из потока в структуру данных, такую как массив байтов.
2. Запись в поток — это передача данных из структуры данных в поток.
3. Потоки также могут поддерживать поиск.
Программы, составленные на языке C#, работают с каталогами, файлами и потоками при помощи специально предназначенных для этого классов, входящих в состав библиотеки классов Microsoft .NET Framework и содержащихся в пространстве имен System.IO, которое необходимо подключить, чтобы обеспечить доступ к классам, определенным для потоков ввода-вывода (см. Пример 7.1).
Для работы с директориями и файлами предназначены следующие основныеклассы:
Directory предоставляет статические методы операций создания, перемещения и перечисления в директориях и поддиректориях. Класс DirectoryInfo предоставляет методы экземпляра.
File предоставляет статические методы для создания, копирования, удаления, перемещения и открытия файлов, а также помогает при создании объектов FileStream. Класс FileInfo предоставляет методы экземпляра.
Для работы с потоками предназначены следующие основныеклассы:
FileStream предоставляет поток в файле, поддерживая операции чтения и записи.
Класс StreamReader считывает символы из потоков с учетом кодировки, класс StreamWriter записывает символы в потоки, используя кодировку для преобразования символов в байты (см. Пример 7.1).
Стандартные потоки связаны, как правило, с консолью и клавиатурой. Для вывода данных в стандартный поток вывода и для ввода из стандартного потока ввода используются методы класса Console: Console.ReadLine, Console.Write и Console.WriteLine. Эти методы и использовались до сих пор во всех примерах программ.
Количество классов, предназначенных для работы с файлами, достаточно велико. Здесь будут рассмотрены только классы, предназначенные для чтения из текстового файла или записи в текстовый файл: StreamReader и StreamWriter.
Для ввода из файла (созданного заранее в текстовом редакторе) необходимо вначале открыть поток класса StreamReader, связав его с файлом. В приведенном ниже примере файл, из которого предполагается считывать данные, расположен по адресу С:\st\Koord.txt (это полный путь к файлу). Открытие потока и его привязка к файлу осуществляются с помощью конструктора (возможны и другие способы, которые здесь не рассматриваются).
StreamReader sr = new StreamReader(path);
Здесь sr – экземпляр класса StreamReader, а аргумент path передает конструктору строку, содержащую полный путь к файлу (в качестве аргумента можно использовать и константу, содержащую полный адрес файла). Далее строки из файла (в программе это поток sr) по очереди считываются в переменную line, из которой далее как обычно извлекаются отдельные значения.
После окончания работы с объявленным потоком, его следует закрыть методом Close
sr.Close();
Пример 7.1. Координаты произвольного количества точек на плоскости размещены в файле Koord.txt на диске С в папке (директории) st по два числа (значения x и y) в строке. В первой строке файла размещено одно число — радиус окружности r. Требуется определить, сколько точек попадет в круг радиуса r.
using System;
using System.IO;
class Program
{
static void Main()
{
string path = "С:\\st \\Koord.txt";
StreamReader sr = new StreamReader(path);
int n = 0;
string line;
line = sr.ReadLine();
int r = int.Parse(line);
Console.WriteLine("Радиус {0}", r);
while ((line = sr.ReadLine()) != null)
{
string[] koord = line.Split(' ');
int x = int.Parse(koord[0]);
int y = int.Parse(koord[1]);
Console.WriteLine("Координаты точек x = {0} y = {1}", x, y);
if (x * x + y * y < r * r) n = n + 1;
}
sr.Close();
Console.WriteLine("{0} точки попадут в круг ", n);
}
}
Замечание. В программе в адресе файла вместо одной наклонной черты используется две. Одна наклонная черта в строке могла бы восприниматься как первый символ управляющей последовательности. Использование двух наклонных позволяет избежать этой двусмысленности. Теперь наклонная черта будет восприниматься как символ строки, а не как управляющая последовательность (см. п. 1.2). В C# предусмотрен также способ объявления строки, в которой все символы между кавычками трактуются как часть строки. Это специальное объявление – буквальные строки – задается указанием символа @ перед всей строкой и обычно используется для задания пути к файлу. С использованием этого объявления задание строки path может выглядеть так
string path = @"С:\st \Koord.txt";
При выводе в файлнеобходимовыполнить аналогичные действия: открыть поток класса StreamWriter, задав имя потока и связав его с файлом, предназначенным для размещения выводимых результатов,вывести в этот поток (т.е. в указанный файл) необходимые результаты и закрыть поток оператором Close().
Если в примере 7.1 предполагается также вывод результата в файл, то необходимо добавить следующие инструкции
string path1 = "c:\\st\\Koord1.txt";
StreamWriter sw = new StreamWriter(path1);
sw.WriteLine(n);
sw.Close();
Далее рассмотрим пример, в котором осуществляется ввод из файла исходных данных и вывод результатов в файл с учетом регионального стандарта (см. Приложение 3).
Пример. 7.2. Протокол соревнований по прыжкам в высоту содержит список фамилий и результатов (одна попытка) в порядке стартовых номеров. Получить итоговую таблицу, содержащую фамилии и результаты в порядке занятых мест. Количество спортсменов не более 30. Для размещения исходных данных используется массив структур. Структура содержит информацию – фамилия и результат спортсмена. Ввод данных осуществлять из заранее подготовленного файла, вывод итоговой таблицы осуществлять в файл. (В примере 4.1 эта же задача решена без использования файлов данных.)
Исходный файл
using System;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
struct Sportsmen
{
public string famile;
public double rez;
}
class Program
{
static void Main(string[] args)
{
Sportsmen[] sp = new Sportsmen[5];
string line;
string path = "c:\\st\\Sportsmen.txt";
//кодовая страница операционной системы Windows для кирилицы имеет
//идентификатор 1251
StreamReader sr = new StreamReader(path,Encoding.GetEncoding(1251));
int i = 0;
while ((line = sr.ReadLine()) != null)
{
string[] sports = line.Split(' ');
sp[i].famile = sports[0];
sp[i].rez = double.Parse(sports[1]);
Console.WriteLine("Фамилия {0}\t Результат {1:f2}",
sp[i].famile, sp[i].rez);
i++;
}
sr.Close();
for (i = 0; i < sp.Length - 1; i++)
{
double amax = sp[i].rez;
int imax = i;
for (int j = i + 1; j < sp.Length; j++)
{
if (sp[j].rez > amax)
{
amax = sp[j].rez;
imax = j;
}
}
Sportsmen temp;
temp = sp[imax];
sp[imax] = sp[i];
sp[i] = temp;
}
Console.WriteLine();
for (i = 0; i < sp.Length; i++)
{
Console.WriteLine("Фамилия {0}\t Результат {1:f2}",
sp[i].famile,sp[i].rez);
}
string path1 = "c:\\st\\Sportsmen1.txt";
StreamWriter sw = new StreamWriter(path1);
for (i = 0; i < sp.Length; i++)
{
sw.WriteLine("{0} {1:f2}", sp[i].famile, sp[i].rez);
}
sw.Close();
}
}
}
Файл с результатами
Замечание. Дополнительно о региональных стандартах см. в Приложении 3.
Вопросы для самопроверки
1. Что такое файл, директория, поддиректория.
2. В чем преимущества использования файлов для ввода и вывода.
3. Что такое поток. Какие операции определены для потока.
4. Открытие потока для чтения и его привязка к файлу.
5. Что такое «полный путь к файлу».
6. Считывание из файла в переменные программы.
7. Открытие потока для вывода и привязка его к файлу, предназначенному для вывода результатов.
8. Закрытие потоков.
Дата добавления: 2015-02-07; просмотров: 1030;