Чтение онлайн

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

После этого можно указать обработку событий Сhanged, Created и Deleted, которые работают в совокупности с делегатом FileSystemEventHandler. Этот делегат может вызывать любой метод, соответствующий следующему шаблону.

// Делегат FileSystemEventHandler должен указывать на методы,

// имеющие следующую сигнатуру.

void MyNotifacationiHandler(object source, FileSystemEventArgs e)

Точно так же событие Renamed можно обработать с помощью типа делегата RenamedEventHandler, способного

вызывать методы, соответствующие следующему шаблону.

// Делегат RenamedEventHandler должен указывать на методы,

// имеющие следующую сигнатуру.

void MyNotificationHandler(object source, RenamedEventArgs e)

Для иллюстрации процесса мониторинга файлов предположим, что мы создали на диске C новый каталог с именем MyFolder, cодержащий различные файлы *.txt (назовите их так, как пожелаете). Следующее консольное приложение осуществляет мониторинг файлов *.txt а каталоге MyFоlder и выводит сообщения о событиях, соответствующих созданию, удалению, изменению или переименованию файлов.

static void Main(string[] args) {

 Console.WriteLine("***** Чудесный монитор файлов *****\n");

 // Установка пути для каталога наблюдения.

 FileSystemWatcher watcher = new FileSystemWatcher;

 try {

watcher.Path = @"C:\MyFolder";

 } catch(ArgumentException ex) {

Console.WriteLine(ex.Message);

return;

 }

 // Установка фильтров наблюдения.

 watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;

 // Наблюдение только за текстовыми файлами.

 watcher.Filter = "*.txt";

 // Добавление обработчиков событий.

 watcher.Changed += new FileSystemEventHandler(OnChanged);

 watcher.Created += new FileSystemEventHandler(OnChanged);

 watcher.Deleted += new FileSystemEventHandler(OnChanged);

 watcher.Renamed += new RenamedEventHandler(OnRenamed);

 // Начало наблюдения за каталогом.

 watcher.EnableRaisingEvents = true;

 // Ожидание сигнала пользователя для выхода из программы.

 Console.WriteLine(@"Нажмите 'q' для выхода из приложения.");

 while(Console.Read != 'q');

}

Следующие два обработчика событий просто выводят информацию о модификации текущего файла.

static void OnChanged(object source, FileSystemEventArgs e) {

 // Уведомление об изменении, создании или удалении файла.

 Console.WriteLine("Файл {0} {1}!", e.FullPath, e.ChangeType);

}

static void OnRenamed(object source, RenamedEventArgs e) {

 //
Уведомление о переименовании файла.

 Console.WriteLine("Файл {0} переименован в\n{1}",

 e.OldFullPath, e.FullPath);

}

Чтобы проверить работу этой программы, запустите приложение и откройте Проводник Windows. Попытайтесь переименовать, создать, удалить файлы *.txt в MyFolder или выполнить с ними какие-то другие действия, вы увидите, что консольное приложение реагирует на эти действия выводом различной информации о состоянии текстовых файлов (рис. 16.10).

Исходный код. Проект MyDirectoryWatcher размещен в подкаталоге, соответствующем главе 16.

Рис. 16.10. Наблюдение за текстовыми файлами

Асинхронный файловый ввод-вывод

В завершение нашего обзора пространства имен System.IO давайте выясним, как осуществляется асинхронное взаимодействие с типами FileStream. Один из вариантов поддержки асинхронного взаимодействия в .NET вы уже видели при рассмотрении многопоточных приложений (см. главу 14). Ввиду того, что ввод-вывод может занимать много времени, все типы, производные от System.IO.Stream, наследуют множество методов, разрешающих асинхронную обработку данных. Как и следует ожидать, эти методы работают в связке с типом IAsyncResult.

public abstract class System.IO.Stream: MarshalByRefObject, IDisposable {

 public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state);

 public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state);

 public virtual int EndRead(IAsyncResult asyncResult); public virtual void EndWrite(IAsyncResult asyncResult);

}

Работа с асинхронными возможностями типов, производных от System. IO.Stream, аналогична работе с асинхронными делегатами и асинхронными удаленными вызовами методов. Маловероятно, что асинхронный подход может существенно улучшить доступ к файлам, но есть большая вероятность того, что от асинхронной обработки получат выгоду другие потоки (например, использующие сокеты). Так или иначе, следующий пример иллюстрирует подход, в рамках которого вы можете асинхронно взаимодействовать с типом FileStream.

class Program {

 static void Main(string[] args) {

Console.WriteLine("Старт первичного потока, ThreadID = {0}", Thread.CurrentThread.GetHashCode);

// Следует использовать этот конструктор, чтобы получить

// FileStream с асинхронным доступом для чтения и записи.

FileStream fs = new FileStream('logfile.txt", FileMode.Append, FileAccess.Write, FileShare.None, 4096, true);

Поделиться с друзьями: