
- •Введение
- •Сравнение языков С++ и C#
- •Логические выражения
- •Функции для ввода и вывода в языке C#
- •Управление форматом числовых данных:
- •Обработка исключительных ситуаций
- •Методы и модификаторы параметров
- •Неявно типизированные переменные
- •Понятие класса
- •Свойства
- •Индексаторы
- •Одномерные индексаторы
- •Многомерные индексаторы
- •Перегрузка методов
- •Перегрузка знаков операций
- •Наследование
- •Виртуальные функции
- •Работа с файлами
- •Работа с каталогами
- •Абстрактный класс FileSystemInfo
- •Класс DirectoryInfo
- •Сериализация
- •FileSystemWatcher – отслеживание событий, связанных с файлами
- •Обобщения (шаблоны)
- •Интерфейсы
- •Коллекции
- •LINQ
- •Грамматика выражений запросов
- •Синтаксис запросов
- •Проекция и фильтрация
- •Упорядочение
- •Агрегирующие запросы
- •Операции с коллекциями
- •Операция Concat
- •Операция Union
- •Преобразование
- •Объединение последовательностей
- •FirstOrDefault
- •Группировка
- •Групповая адресация
- •Обработка событий
- •Групповое преобразование делегируемых методов
- •Применение методов экземпляра в качестве делегатов
- •Групповая адресация
- •Ковариантность и контравариантность
- •Класс System. Delegate
- •Назначение делегатов
- •Анонимные функции
- •Анонимные методы
- •Передача аргументов анонимному методу
- •Возврат значения из анонимного метода
- •Применение внешних переменных в анонимных методах
- •Лямбда-выражения
- •Лямбда-оператор
- •Одиночные лямбда-выражения
- •Блочные лямбда-выражения
- •События
- •Пример групповой адресации события
- •Применение аксессоров событий
- •Разнообразные возможности событий
- •Применение анонимных методов и лямбда-выражений вместе с событиями
- •Рекомендации по обработке событий в среде .NET Framework
- •Применение делегатов EventHandler<TEventArgs> и EventHandler
- •Практический пример обработки событий

Чернов Э. А. |
- 71 - |
Лекции по языку C# v 2.3 |
Ниже приведен пример, в котором данные из одного файла копируются в другой с использованием классов StreamWriter и StreamReader. При чтении указана кодировка по умолчанию (Default, так проще, чтобы не думать, в какой кодировке записан файл). При записи выполняется переписывание файла.
static void Main()
{
StreamReader FileIn = new StreamReader("C:\\Text.txt",Encoding.Default); StreamWriter FileOut = new StreamWriter("C:\\RetText.txt",false);
string str;
while ((str = FileIn.ReadLine()) != null) // Пока не конец файла
{
FileOut.WriteLine(str);
}
FileIn.Close();
FileOut.Close();
}
Обратите внимание: чтение из файла выполнено в заголовке цикла, но оператор заключен в скобки (str = FileIn.ReadLine()), поскольку не разрешается применять в условии операцию равенства.
Отметим, что все методы ввода и вывода имеют разновидность с добавлением слова Async (например, WriteLineAsync, ReadAsync и т. д.), которое указывает на то, что операция выполняется асинхронно. В этом варианте предусматривается выполнение операции в другом потоке процесса.
Работа с каталогами
Абстрактный класс FileSystemInfo
Значительная часть членов FileSystemInfo предназначена для работы с общими характеристиками файла или каталога (метками времени, атрибутами и т. п.). Рассмотрим некоторые свойства FileSystemInfo:
Свойство
Attributes
CreationTime
Exists
Extension
FullName
LastAccessTime
Описание
Используется для получения или установки атрибуты для данного объекта файловой системы. Для этого свойства используются значения и перечисления FileAttributes
Позволяет получить или установить время создания объекта файловой системы
Используется для проверки существования данного файла или папки.
Позволяет получить расширение для файла
Возвращает имя файла или каталога с указанием пути к нему в файловой системе
Позволяет получить или установить время последнего обраще-

Чернов Э. А.
LastWriteTime
Name
- 72 - |
Лекции по языку C# v 2.3 |
ния к объекту файловой системы |
|
Позволяет получить или установить время последнего внесения изменений в объект файловой системы
Возвращает имя указанного файла. Это свойство доступно только для чтения. Для каталогов возвращает имя последнего каталога в иерархии, если это возможно. Если нет, возвращает полностью определенное имя
В классе FileSystemInfo предусмотрено и несколько методов. Например, метод Delete() - позволяет удалить объект файловой системы с жесткого диска, а Refresh() — обновить информацию об объекте файловой системы.
Класс DirectoryInfo
Данный класс является производным от класса FileSystemInfo и содержит элементы для создания, перемещения, удаления файлов и папок, а также для получения информации о каталогах и подкаталогах. Основные члены класса содержатся в таблице ниже:
Член |
Описание |
Create() |
Эти методы предназначены для создания основных и |
CreateSubDirectory() |
вложенных папок по заданному пути |
Delete() |
Этот метод позволяет удалить пустой каталог |
GetDirectories() |
Этот метод позволяет получить список вложенных па- |
|
пок текущего каталога. |
GetFiles() |
Этот метод позволяет получить список файлов текуще- |
|
го каталога. |
MoveTo() |
Этот метод обеспечивает перемещение папки и ее со- |
|
держимого по новому пути |
Parent |
Этот метод возвращает имя родительской папки. |
Для доступа к методам класса DirectoryInfo надо объявить объект этого класса, указав путь к требуемой папке в качестве параметра в конструкторе. Для обращения к текущей папке (из которой запущено приложение) в качестве параметра задается строка: ".". Например:
//Объявление объекта DirectoryInfo в качестве текущей папки
DirectoryInfo CurDir = new DirectoryInfo(".");
//Объявление объекта DirectoryInfo в качестве новой папки
DirectoryInfo NewDir = new DirectoryInfo("C:\\Temp");
Впримере ниже объявлен объект класса DirectoryInfo, входящий в папку C:\Temp. Для получения информации о новой папке можно использовать приведенный ниже фрагмент программы. Информацию можно получить только о существующей папке.
static void Main(string[] args)
{
DirectoryInfo NewFolder = new DirectoryInfo ("C:\\Temp\\Temp1"); Console.WriteLine("Содержимое папки: ", NewFolder.Name);

Чернов Э. А. |
- 73 - |
Лекции по языку C# v 2.3 |
Console.WriteLine("Полный путь: {0}", NewFolder.FullName); Console.WriteLine("Имя: {0}", NewFolder.Name);
Console.WriteLine("Родительская папка: {0}", NewFolder.Parent); Console.WriteLine("Дата создания: {0}", NewFolder.CreationTime);
Console.WriteLine("Атрибуты: {0}", NewFolder.Attributes.ToString()); Console.WriteLine("Корневая папка: {0}", NewFolder.Root);
}
Вывод для приведенного фрагмента программы:
Вывод в случае указания пути в виде ".": (Приведен полный путь папки, из которой запущено консольное приложение).
Возможные значения атрибутов для заданной папки приведены в таблице ниже:
Значение |
Описание |
Archive |
Этот атрибут используется приложениями при проведении резерв- |
|
ного копирования, а в некоторых случаях — удаления старых фай- |
|
лов |
Compressed |
Определяет, что файл является сжатым |
Directory |
Определяет, что объект файловой системы является каталогом |
Encrypted |
Определяет, что файл является зашифрованным |
Hidden |
Определяет, что файл является скрытым (такой файл не будет вы- |
|
водиться при обычном просмотре каталога) |
Normal |
Определяет, что файл находится в обычном состоянии и для него |
|
установлены любые другие атрибуты. Этот атрибут не может ис- |
|
пользоваться с другими атрибутами |
Readonly |
Файл доступен только для чтения |
System |
Файл является системным (то есть файл является частью операци- |
|
онной системы или используется исключительно операционной |
|
системой) |
Через объект класса DirectoryInfo можно получать информацию не только о текущей папке, но и о вложенных папках:
static void Main(string[ ] args)
{
DirectoryInfo Fold = new DirectoryInfo("C:\\Workc"); Console.Write("Корневая папка: \n", Fold.Name); Console.WriteLine(" {0}", Fold);

Чернов Э. А. |
- 74 - |
Лекции по языку C# v 2.3 |
DirectoryInfo[ ] subDirects = Fold.GetDirectories(); Console.WriteLine("Вложенных папок: {0}", subDirects.Length); foreach (DirectoryInfo d in subDirects)
{
Console.WriteLine(" {0}", d);
}
Console.ReadKey();
}
Вывод программы
Класс FileInfo позволяет получить информацию о файле. Ниже приведена программа для получения такой информации.
static void Main(string[] args)
{
FileInfo MyFile = new FileInfo("C:\\Temp\\CrText.txt"); Console.WriteLine("Описание файла: ", MyFile.Name); Console.WriteLine("Полный путь: {0}", MyFile.FullName); Console.WriteLine("Имя: {0}", MyFile.Name); Console.WriteLine("Дата создания: {0}", MyFile.CreationTime); Console.WriteLine("Атрибуты: {0}", MyFile.Attributes.ToString()); Console.ReadKey();//
}
Вывод программы
Сериализация
Сериализацией называется процесс сохранения объектов в файле в виде последовательности двоичных разрядов. Процесс восстановления объектов из файла называется десериализацией. Имеется в виду, что содержимое объекта, состоящее из данных разных типов и длины сохраняются в виде единого блока двоичных разрядов.
Существует несколько способов сериализации объектов (Soap – Simple Object Access Protocol).
BinaryFormatter
SoapFormatter(Soap – Simple Object Access Protocol)
Чернов Э. А. |
- 75 - |
Лекции по языку C# v 2.3 |
XmlSerializer
Далее рассматривается только класс BinaryFormatter
При этом программа, выполняющая сериализацию, с помощью класса BinaryFormatter, находящегося в пространстве имен
Sytem.Runtime.Serialization.Formatters.Binary, заносит в файл информацию, необ-
ходимую для восстановления объекта.
Класс, в котором реализуется сериализация (десереализация) должен иметь атрибут Serializable (Этот атрибут записывается в квадратных скобках перед именем класса). Собственно сериализацию и десериализацию выполняют методы этого класса: Serialize() и Desirealize().
В простейшем случае методе Serialize создается список объектов для сериализации, открывается файл, в котором будет выполняться сериализация, и выполняется сериализация. В методе Deserialize выполняется восстановление списка.
Ниже приведен пример.
[Serializable] class Program
{
static void Main(string[] args)
{
Serialize();
Deserialize(); Console.ReadKey();
}
//
static void Serialize()
{
// Создание списка для сериализации
List<string> famLst = new List<string>(); famLst.Add("Иванов"); famLst.Add("Петров"); famLst.Add("Сидоров");
// Открытие файла для записи
FileStream fst = new FileStream("C:\\Temp\\Myfile.t", FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
BinaryFormatter bf = new BinaryFormatter(); // Собственно сериализация bf.Serialize(fst, famLst);
fst.Close();
}
static void Deserialize()
{
List<string> famLst;
FileStream fst = new FileStream("C:\\Temp\\Myfile.t", FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryFormatter bf=new BinaryFormatter(); famLst = (List<string>)bf.Deserialize(fst);
Чернов Э. А. |
- 76 - |
Лекции по языку C# v 2.3 |
fst.Close();
// Распечатка восстановленного списка foreach (string fl in famLst)
{
Console.WriteLine(fl);
}
}
}
Для сериализации объектов, состоящих из разнотипных данных надо описать класс с атрибутом ISerializable.
Ниже приведен пример
[Serializable]
public class MyObject
{
public int n1 = 0; public int n2 = 0; public String str = null;
}
class Program
{
static void Main(string[] args)
{
MyObject obj = new MyObject(); obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("C:\\Tst\\MyFile.bin",
FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, obj);
stream.Close();
stream = new FileStream("C:\\Tst\\MyFile.bin",
FileMode.Open, FileAccess.Read, FileShare.Read);
// Десериализация
obj = (MyObject) formatter.Deserialize(stream); stream.Close();
// Проверка
Console.WriteLine("n1: {0}", obj.n1); Console.WriteLine("n2: {0}", obj.n2); Console.WriteLine("str: {0}", obj.str); Console.ReadKey();
}
}
Сохранение в файле коллекций будет рассмотрено далее.